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
|
# XSD4R - XML Schema Namespace library
# Copyright (C) 2000-2003, 2005 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
class Assigner
def initialize
@count = 0
end
def assign(ns)
@count += 1
"n#{@count}"
end
end
attr_reader :default_namespace
class FormatError < Error; end
public
def initialize(tag2ns = {})
@tag2ns = tag2ns
@assigner = nil
@ns2tag = {}
@tag2ns.each do |tag, ns|
@ns2tag[ns] = tag
end
@default_namespace = nil
end
def assign(ns, tag = nil)
if (tag == '')
@default_namespace = ns
tag
else
@assigner ||= Assigner.new
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_tag?(tag)
@tag2ns.key?(tag)
end
def clone_ns
cloned = NS.new(@tag2ns.dup)
cloned.assigner = @assigner
cloned.assign(@default_namespace, '') if @default_namespace
cloned
end
def name(name)
if (name.namespace == @default_namespace)
name.name
elsif @ns2tag.key?(name.namespace)
"#{@ns2tag[name.namespace]}:#{name.name}"
else
raise FormatError.new("namespace: #{name.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('^([^:]+)(?::(.+))?$')
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
end
end
|