1 | # XSD4R - XML Schema Namespace library
|
---|
2 | # Copyright (C) 2000-2003, 2005 NAKAMURA, Hiroshi <[email protected]>.
|
---|
3 |
|
---|
4 | # This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
---|
5 | # redistribute it and/or modify it under the same terms of Ruby's license;
|
---|
6 | # either the dual license version in 2003, or any later version.
|
---|
7 |
|
---|
8 |
|
---|
9 | require 'xsd/datatypes'
|
---|
10 |
|
---|
11 |
|
---|
12 | module XSD
|
---|
13 |
|
---|
14 |
|
---|
15 | class NS
|
---|
16 | class Assigner
|
---|
17 | def initialize
|
---|
18 | @count = 0
|
---|
19 | end
|
---|
20 |
|
---|
21 | def assign(ns)
|
---|
22 | @count += 1
|
---|
23 | "n#{@count}"
|
---|
24 | end
|
---|
25 | end
|
---|
26 |
|
---|
27 | attr_reader :default_namespace
|
---|
28 |
|
---|
29 | class FormatError < Error; end
|
---|
30 |
|
---|
31 | public
|
---|
32 |
|
---|
33 | def initialize(tag2ns = {})
|
---|
34 | @tag2ns = tag2ns
|
---|
35 | @assigner = nil
|
---|
36 | @ns2tag = {}
|
---|
37 | @tag2ns.each do |tag, ns|
|
---|
38 | @ns2tag[ns] = tag
|
---|
39 | end
|
---|
40 | @default_namespace = nil
|
---|
41 | end
|
---|
42 |
|
---|
43 | def assign(ns, tag = nil)
|
---|
44 | if (tag == '')
|
---|
45 | @default_namespace = ns
|
---|
46 | tag
|
---|
47 | else
|
---|
48 | @assigner ||= Assigner.new
|
---|
49 | tag ||= @assigner.assign(ns)
|
---|
50 | @ns2tag[ns] = tag
|
---|
51 | @tag2ns[tag] = ns
|
---|
52 | tag
|
---|
53 | end
|
---|
54 | end
|
---|
55 |
|
---|
56 | def assigned?(ns)
|
---|
57 | @default_namespace == ns or @ns2tag.key?(ns)
|
---|
58 | end
|
---|
59 |
|
---|
60 | def assigned_tag?(tag)
|
---|
61 | @tag2ns.key?(tag)
|
---|
62 | end
|
---|
63 |
|
---|
64 | def clone_ns
|
---|
65 | cloned = NS.new(@tag2ns.dup)
|
---|
66 | cloned.assigner = @assigner
|
---|
67 | cloned.assign(@default_namespace, '') if @default_namespace
|
---|
68 | cloned
|
---|
69 | end
|
---|
70 |
|
---|
71 | def name(name)
|
---|
72 | if (name.namespace == @default_namespace)
|
---|
73 | name.name
|
---|
74 | elsif @ns2tag.key?(name.namespace)
|
---|
75 | "#{@ns2tag[name.namespace]}:#{name.name}"
|
---|
76 | else
|
---|
77 | raise FormatError.new("namespace: #{name.namespace} not defined yet")
|
---|
78 | end
|
---|
79 | end
|
---|
80 |
|
---|
81 | def compare(ns, name, rhs)
|
---|
82 | if (ns == @default_namespace)
|
---|
83 | return true if (name == rhs)
|
---|
84 | end
|
---|
85 | @tag2ns.each do |assigned_tag, assigned_ns|
|
---|
86 | if assigned_ns == ns && "#{assigned_tag}:#{name}" == rhs
|
---|
87 | return true
|
---|
88 | end
|
---|
89 | end
|
---|
90 | false
|
---|
91 | end
|
---|
92 |
|
---|
93 | # $1 and $2 are necessary.
|
---|
94 | ParseRegexp = Regexp.new('^([^:]+)(?::(.+))?$')
|
---|
95 |
|
---|
96 | def parse(str, local = false)
|
---|
97 | if ParseRegexp =~ str
|
---|
98 | if (name = $2) and (ns = @tag2ns[$1])
|
---|
99 | return XSD::QName.new(ns, name)
|
---|
100 | end
|
---|
101 | end
|
---|
102 | XSD::QName.new(local ? nil : @default_namespace, str)
|
---|
103 | end
|
---|
104 |
|
---|
105 | # For local attribute key parsing
|
---|
106 | # <foo xmlns="urn:a" xmlns:n1="urn:a" bar="1" n1:baz="2" />
|
---|
107 | # =>
|
---|
108 | # {}bar, {urn:a}baz
|
---|
109 | def parse_local(elem)
|
---|
110 | ParseRegexp =~ elem
|
---|
111 | if $2
|
---|
112 | ns = @tag2ns[$1]
|
---|
113 | name = $2
|
---|
114 | if !ns
|
---|
115 | raise FormatError.new("unknown namespace qualifier: #{$1}")
|
---|
116 | end
|
---|
117 | elsif $1
|
---|
118 | ns = nil
|
---|
119 | name = $1
|
---|
120 | else
|
---|
121 | raise FormatError.new("illegal element format: #{elem}")
|
---|
122 | end
|
---|
123 | XSD::QName.new(ns, name)
|
---|
124 | end
|
---|
125 |
|
---|
126 | def each_ns
|
---|
127 | @ns2tag.each do |ns, tag|
|
---|
128 | yield(ns, tag)
|
---|
129 | end
|
---|
130 | end
|
---|
131 |
|
---|
132 | protected
|
---|
133 |
|
---|
134 | def assigner=(assigner)
|
---|
135 | @assigner = assigner
|
---|
136 | end
|
---|
137 | end
|
---|
138 |
|
---|
139 |
|
---|
140 | end
|
---|