1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
# XSD4R - XML Schema Namespace library
# Copyright (C) 2000-2007 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
# redistribute it and/or modify it under the same terms of Ruby's license;
# either the dual license version in 2003, or any later version.
require 'xsd/datatypes'
module XSD
class NS
Namespace = 'http://www.w3.org/XML/1998/namespace'
KNOWN_TAG = {
XSD::Namespace => 'xsd',
XSD::InstanceNamespace => 'xsi',
}
class Assigner
attr_reader :known_tag
def initialize(known_tag)
@known_tag = known_tag.dup
@count = 0
end
def assign(ns)
if @known_tag.key?(ns)
return @known_tag[ns]
end
@count += 1
"n#{@count}"
end
end
attr_reader :default_namespace
class FormatError < Error; end
public
def initialize(tag2ns = nil)
@tag2ns = tag2ns || ns_default
@ns2tag = @tag2ns.invert
@assigner = nil
@default_namespace = nil
end
def known_tag
@assigner ||= Assigner.new(default_known_tag)
@assigner.known_tag
end
def assign(ns, tag = nil)
if tag == ''
if ns.empty?
@default_namespace = nil
else
@default_namespace = ns
end
tag
else
@assigner ||= Assigner.new(default_known_tag)
tag ||= @assigner.assign(ns)
@ns2tag[ns] = tag
@tag2ns[tag] = ns
tag
end
end
def assigned?(ns)
@default_namespace == ns or @ns2tag.key?(ns)
end
def assigned_as_tagged?(ns)
@ns2tag.key?(ns)
end
def assigned_tag?(tag)
@tag2ns.key?(tag)
end
def clone_ns
cloned = self.class.new(@tag2ns.dup)
cloned.assigner = @assigner
cloned.assign(@default_namespace, '') if @default_namespace
cloned
end
def name(qname)
if qname.namespace == @default_namespace
qname.name
elsif tag = @ns2tag[qname.namespace]
"#{tag}:#{qname.name}"
else
raise FormatError.new("namespace: #{qname.namespace} not defined yet")
end
end
# no default namespace
def name_attr(qname)
if tag = @ns2tag[qname.namespace]
"#{tag}:#{qname.name}"
else
raise FormatError.new("namespace: #{qname.namespace} not defined yet")
end
end
def compare(ns, name, rhs)
if (ns == @default_namespace)
return true if (name == rhs)
end
@tag2ns.each do |assigned_tag, assigned_ns|
if assigned_ns == ns && "#{assigned_tag}:#{name}" == rhs
return true
end
end
false
end
# $1 and $2 are necessary.
ParseRegexp = Regexp.new('\A([^:]+)(?::(.+))?\z')
def parse(str, local = false)
if ParseRegexp =~ str
if (name = $2) and (ns = @tag2ns[$1])
return XSD::QName.new(ns, name)
end
end
XSD::QName.new(local ? nil : @default_namespace, str)
end
# For local attribute key parsing
# <foo xmlns="urn:a" xmlns:n1="urn:a" bar="1" n1:baz="2" />
# =>
# {}bar, {urn:a}baz
def parse_local(elem)
ParseRegexp =~ elem
if $2
ns = @tag2ns[$1]
name = $2
if !ns
raise FormatError.new("unknown namespace qualifier: #{$1}")
end
elsif $1
ns = nil
name = $1
else
raise FormatError.new("illegal element format: #{elem}")
end
XSD::QName.new(ns, name)
end
def each_ns
@ns2tag.each do |ns, tag|
yield(ns, tag)
end
end
protected
def assigner=(assigner)
@assigner = assigner
end
private
def ns_default
{'xml' => Namespace}
end
def default_known_tag
KNOWN_TAG
end
end
end
|