xamplr 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.txt +13 -0
- data/LICENSE +3 -0
- data/README.rdoc +26 -0
- data/README.rdoc.orig +118 -0
- data/Rakefile +85 -0
- data/VERSION.yml +4 -0
- data/examples/random-people-shared-addresses/Makefile +16 -0
- data/examples/random-people-shared-addresses/batch-load-users.rb +83 -0
- data/examples/random-people-shared-addresses/find-mentions.rb +47 -0
- data/examples/random-people-shared-addresses/find-people-by-address.rb +104 -0
- data/examples/random-people-shared-addresses/optimise.rb +16 -0
- data/examples/random-people-shared-addresses/people.rb +35 -0
- data/examples/random-people-shared-addresses/query.rb +75 -0
- data/examples/random-people-shared-addresses/query2.rb +73 -0
- data/examples/random-people-shared-addresses/random-names.csv +10000 -0
- data/examples/random-people-shared-addresses/settings.rb +3 -0
- data/examples/random-people-shared-addresses/what-to-query-on.rb +82 -0
- data/examples/random-people-shared-addresses/xampl-gen.rb +36 -0
- data/examples/random-people-shared-addresses/xml/people.xml +14 -0
- data/examples/random-people/Makefile +16 -0
- data/examples/random-people/batch-load-users.rb +61 -0
- data/examples/random-people/optimise.rb +16 -0
- data/examples/random-people/people.rb +22 -0
- data/examples/random-people/query.rb +73 -0
- data/examples/random-people/query2.rb +73 -0
- data/examples/random-people/random-names.csv +10000 -0
- data/examples/random-people/rawtc.rb +91 -0
- data/examples/random-people/settings.rb +3 -0
- data/examples/random-people/what-to-query-on.rb +80 -0
- data/examples/random-people/xampl-gen.rb +36 -0
- data/examples/random-people/xml/people.xml +11 -0
- data/examples/read-testing/Makefile +10 -0
- data/examples/read-testing/load.rb +65 -0
- data/examples/read-testing/read.rb +51 -0
- data/examples/read-testing/rrr.rb +87 -0
- data/examples/read-testing/settings.rb +2 -0
- data/examples/read-testing/xampl-gen.rb +36 -0
- data/examples/read-testing/xml/text.xml +8 -0
- data/examples/tokyo-cabinet-experimental/expt-query.rb +42 -0
- data/examples/tokyo-cabinet-experimental/expt-query2.rb +42 -0
- data/examples/tokyo-cabinet-experimental/expt-query3.rb +41 -0
- data/examples/tokyo-cabinet-experimental/expt-reader.rb +32 -0
- data/examples/tokyo-cabinet-experimental/expt.rb +61 -0
- data/examples/tokyo-cabinet-experimental/xampl-gen.rb +36 -0
- data/examples/tokyo-cabinet-experimental/xml/tcx.xml +6 -0
- data/lib/xampl-generator.rb +3 -0
- data/lib/xampl.rb +3 -0
- data/lib/xamplr-generator.rb +10 -0
- data/lib/xamplr.rb +37 -0
- data/lib/xamplr/README-POSSIBLE-PROBLEMS +5 -0
- data/lib/xamplr/TODO +1 -0
- data/lib/xamplr/exceptions.rb +97 -0
- data/lib/xamplr/from-xml-orig.rb +350 -0
- data/lib/xamplr/from-xml.rb +439 -0
- data/lib/xamplr/gen-elements.xml +6230 -0
- data/lib/xamplr/gen.elements.xml +108 -0
- data/lib/xamplr/generate-elements.rb +15 -0
- data/lib/xamplr/generator.rb +5 -0
- data/lib/xamplr/graphml-out.rb +470 -0
- data/lib/xamplr/handwritten/example.rb +698 -0
- data/lib/xamplr/handwritten/hand-example.rb +533 -0
- data/lib/xamplr/handwritten/test-handwritten.rb +873 -0
- data/lib/xamplr/indexed-array.rb +115 -0
- data/lib/xamplr/mixins.rb +397 -0
- data/lib/xamplr/my.gen.elements.xml +461 -0
- data/lib/xamplr/notifications.rb +57 -0
- data/lib/xamplr/obsolete/fsdb.rb +62 -0
- data/lib/xamplr/persist-to-xml.rb +249 -0
- data/lib/xamplr/persistence.rb +522 -0
- data/lib/xamplr/persistence.rb.more_thread_safe +771 -0
- data/lib/xamplr/persistence.rb.partially_thread_safe +763 -0
- data/lib/xamplr/persister.rb +310 -0
- data/lib/xamplr/persisters/caches.rb +186 -0
- data/lib/xamplr/persisters/caching.rb +172 -0
- data/lib/xamplr/persisters/filesystem.rb +60 -0
- data/lib/xamplr/persisters/in-memory.rb +180 -0
- data/lib/xamplr/persisters/simple.rb +59 -0
- data/lib/xamplr/persisters/tokyo-cabinet.rb +641 -0
- data/lib/xamplr/simpleTemplate/danger.rx +4 -0
- data/lib/xamplr/simpleTemplate/obsolete/input-c.r4 +35 -0
- data/lib/xamplr/simpleTemplate/obsolete/play.r6.txt +12 -0
- data/lib/xamplr/simpleTemplate/obsolete/play_more.r6.txt +20 -0
- data/lib/xamplr/simpleTemplate/obsolete/test001.r5 +8 -0
- data/lib/xamplr/simpleTemplate/obsolete/test002.r5 +13 -0
- data/lib/xamplr/simpleTemplate/obsolete/test003.r5 +37 -0
- data/lib/xamplr/simpleTemplate/old/r6.000.rb +122 -0
- data/lib/xamplr/simpleTemplate/old/r6.001.rb +145 -0
- data/lib/xamplr/simpleTemplate/play.r6 +12 -0
- data/lib/xamplr/simpleTemplate/play_more.r6 +20 -0
- data/lib/xamplr/simpleTemplate/play_noblanks.r6 +21 -0
- data/lib/xamplr/simpleTemplate/playq.r6 +16 -0
- data/lib/xamplr/simpleTemplate/r6.rb +87 -0
- data/lib/xamplr/simpleTemplate/simple-template.rb +75 -0
- data/lib/xamplr/templates/child.template +47 -0
- data/lib/xamplr/templates/child_indexed.template +89 -0
- data/lib/xamplr/templates/child_modules.template +5 -0
- data/lib/xamplr/templates/element_classes.template +11 -0
- data/lib/xamplr/templates/element_data.template +282 -0
- data/lib/xamplr/templates/element_empty.template +285 -0
- data/lib/xamplr/templates/element_mixed.template +277 -0
- data/lib/xamplr/templates/element_simple.template +276 -0
- data/lib/xamplr/templates/package.template +26 -0
- data/lib/xamplr/test-support/Makefile +47 -0
- data/lib/xamplr/test-support/bench-cache.rb +80 -0
- data/lib/xamplr/test-support/bench-script.rb +21 -0
- data/lib/xamplr/test-support/bench.rb +116 -0
- data/lib/xamplr/test-support/bench2.rb +132 -0
- data/lib/xamplr/test-support/test-cache.rb +147 -0
- data/lib/xamplr/test-support/test-data/binding.xml +7 -0
- data/lib/xamplr/test-support/test-data/example.xml +14 -0
- data/lib/xamplr/test-support/test-data/internationalization-utf8.txt +1 -0
- data/lib/xamplr/test-support/test-data/labels.xml +37 -0
- data/lib/xamplr/test-support/test-data/labels001.xml +38 -0
- data/lib/xamplr/test-support/test-deep-change.rb +135 -0
- data/lib/xamplr/test-support/test-elements.rb +109 -0
- data/lib/xamplr/test-support/test-indexed-array.rb +169 -0
- data/lib/xamplr/test-support/test-misc.rb +73 -0
- data/lib/xamplr/test-support/test-names.rb +67 -0
- data/lib/xamplr/test-support/test-rollback.rb +106 -0
- data/lib/xamplr/test-support/test.rb +1504 -0
- data/lib/xamplr/to-ruby.rb +220 -0
- data/lib/xamplr/to-xml.rb +158 -0
- data/lib/xamplr/version.rb +67 -0
- data/lib/xamplr/visitor.rb +140 -0
- data/lib/xamplr/visitors.rb +573 -0
- data/lib/xamplr/xampl-generator.rb +533 -0
- data/lib/xamplr/xampl-hand-generated.rb +1535 -0
- data/lib/xamplr/xampl-module.rb +36 -0
- data/lib/xamplr/xampl-object-internals.rb +6 -0
- data/lib/xamplr/xampl-object.rb +202 -0
- data/lib/xamplr/xampl-persisted-object.rb +122 -0
- data/lib/xamplr/xml-text.rb +117 -0
- data/lib/xamplr/xml/document.xml +7 -0
- data/lib/xamplr/xml/elements.xml +101 -0
- data/lib/xamplr/xml/elements000.xml +73 -0
- data/lib/xamplr/xml/example.xml +23 -0
- data/lib/xamplr/xml/options.xml +12 -0
- data/lib/xamplr/xml/uche.xml +38 -0
- data/lib/xamplr/yEd-sample.graphml +300 -0
- data/test/test_helper.rb +10 -0
- data/test/xamplr_test.rb +7 -0
- metadata +245 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
require "xamplr-pp"
|
|
2
|
+
|
|
3
|
+
module Xampl
|
|
4
|
+
|
|
5
|
+
class FromXML_original < Xampl_PP
|
|
6
|
+
|
|
7
|
+
attr :checkWellFormed, false
|
|
8
|
+
attr :is_realising, false
|
|
9
|
+
attr :tokenise_content, false
|
|
10
|
+
|
|
11
|
+
@@by_tag = {}
|
|
12
|
+
@@by_ns_tag = {}
|
|
13
|
+
|
|
14
|
+
def initialize(recovering=false)
|
|
15
|
+
super()
|
|
16
|
+
@recovering = recovering
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def FromXML_original.reset_registry
|
|
20
|
+
@@by_tag = {}
|
|
21
|
+
@@by_ns_tag = {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def FromXML_original.register(tag, ns_tag, klass)
|
|
25
|
+
@@by_ns_tag[ns_tag] = [ klass ]
|
|
26
|
+
a = @@by_tag[tag]
|
|
27
|
+
if (nil == a) then
|
|
28
|
+
@@by_tag[tag] = [ klass ]
|
|
29
|
+
else
|
|
30
|
+
found = false
|
|
31
|
+
a.each { | thing | found = found | (thing == klass) }
|
|
32
|
+
a << klass unless found
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def FromXML_original.registered(name)
|
|
37
|
+
klass = @@by_ns_tag[name]
|
|
38
|
+
klass = @@by_tag[name] unless klass
|
|
39
|
+
klass = [] unless klass
|
|
40
|
+
return klass
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def resolve(name)
|
|
44
|
+
return name
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def setup_parse(filename, tokenise_content=true, is_realising=false)
|
|
48
|
+
@processNamespace = true
|
|
49
|
+
@reportNamespaceAttributes = false
|
|
50
|
+
@checkWellFormed = false
|
|
51
|
+
@resolver = self
|
|
52
|
+
|
|
53
|
+
@is_realising = is_realising
|
|
54
|
+
@tokenise_content = tokenise_content
|
|
55
|
+
|
|
56
|
+
setInput(File.new(filename))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def setup_parse_string(string, tokenise_content=true, is_realising=false)
|
|
60
|
+
@processNamespace = true
|
|
61
|
+
@reportNamespaceAttributes = false
|
|
62
|
+
@checkWellFormed = false
|
|
63
|
+
@resolver = self
|
|
64
|
+
|
|
65
|
+
@is_realising = is_realising
|
|
66
|
+
@tokenise_content = tokenise_content
|
|
67
|
+
|
|
68
|
+
setInput(string)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def parse(filename, tokenise_content=true, is_realising=false)
|
|
72
|
+
begin
|
|
73
|
+
setup_parse(filename, tokenise_content, is_realising)
|
|
74
|
+
element, ignore = parse_element
|
|
75
|
+
return element
|
|
76
|
+
rescue Exception => e
|
|
77
|
+
puts "trouble parsing file: '#{filename}'"
|
|
78
|
+
puts "Exception: #{e}"
|
|
79
|
+
raise
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def realise_string(string, tokenise_content=true, target=nil)
|
|
84
|
+
return parse_string(string, tokenise_content, true, target)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def parse_string(string, tokenise_content=true, is_realising=false, target=nil)
|
|
88
|
+
begin
|
|
89
|
+
setup_parse_string(string, tokenise_content, is_realising)
|
|
90
|
+
element, ignore = parse_element(nil, target)
|
|
91
|
+
return element
|
|
92
|
+
rescue Exception => e
|
|
93
|
+
puts "trouble parsing string: '#{string}'"
|
|
94
|
+
puts "Exception: #{e}"
|
|
95
|
+
raise
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def FromXML_original.tokenise_string(str, strip=true)
|
|
100
|
+
return nil unless str
|
|
101
|
+
str.strip! if strip
|
|
102
|
+
str.gsub!(/[ \n\r\t][ \n\r\t]*/, " ")
|
|
103
|
+
return str
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def parse_element(parent=nil, target=nil)
|
|
107
|
+
next_interesting_event unless parent
|
|
108
|
+
|
|
109
|
+
existing_element = nil
|
|
110
|
+
element = nil
|
|
111
|
+
|
|
112
|
+
requires_caching = false
|
|
113
|
+
|
|
114
|
+
if startElement? then
|
|
115
|
+
if ((nil != @namespace) and (0 < @namespace.size)) then
|
|
116
|
+
klass_name = "{#{@namespace}}#{@name}"
|
|
117
|
+
klasses = FromXML_original.registered(klass_name)
|
|
118
|
+
if (0 == klasses.size) then
|
|
119
|
+
xml_text = XMLText.new
|
|
120
|
+
xml_text.build(self)
|
|
121
|
+
xml_text = parent.note_adding_text_content(xml_text, @is_realising)
|
|
122
|
+
parent.add_content(xml_text, @tokenise_content) if xml_text
|
|
123
|
+
# puts "#{__LINE__ }:: add_content [#{xml_text}] --> [#{parent.content}]"
|
|
124
|
+
return xml_text, false
|
|
125
|
+
end
|
|
126
|
+
if (1 < klasses.size) then
|
|
127
|
+
raise XamplException.new("there is more than one '#{@name}' tag in namespace '#{@namespace}'\nplease report this error")
|
|
128
|
+
end
|
|
129
|
+
else
|
|
130
|
+
klasses = FromXML_original.registered(@name)
|
|
131
|
+
if (0 == klasses.size) then
|
|
132
|
+
raise XamplException.new("do not recognise tag '#{@name}' (no namespace specified)")
|
|
133
|
+
end
|
|
134
|
+
if (1 < klasses.size) then
|
|
135
|
+
raise XamplException.new("there is more than one '#{@name}' tag (no namespace specified)")
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
unless @is_realising then
|
|
140
|
+
@attributeValue.size.times do |i|
|
|
141
|
+
FromXML_original.tokenise_string @attributeValue[i]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
if target then
|
|
146
|
+
element = target
|
|
147
|
+
target.load_needed = false
|
|
148
|
+
target = nil
|
|
149
|
+
element.init_attributes(@attributeName, @attributeNamespace, @attributeValue)
|
|
150
|
+
element.note_attributes_initialised(@is_realising)
|
|
151
|
+
else
|
|
152
|
+
if klasses[0].persisted? then
|
|
153
|
+
@attributeName.each_index do |i|
|
|
154
|
+
if @attributeName[i] == klasses[0].persisted?.to_s then
|
|
155
|
+
existing_element = Xampl.find_known(klasses[0], @attributeValue[i])
|
|
156
|
+
if existing_element then
|
|
157
|
+
# so we've found the element. Now what??? We can do several
|
|
158
|
+
# reasonable things:
|
|
159
|
+
#
|
|
160
|
+
# 1) continue parsing into the found element
|
|
161
|
+
# 2) simply return the found element
|
|
162
|
+
# 3) replace the found element with the new element
|
|
163
|
+
#
|
|
164
|
+
# The first one is dubious, so we won't.
|
|
165
|
+
# The second and third option both make complete sense
|
|
166
|
+
#
|
|
167
|
+
# We are going to do the second
|
|
168
|
+
#
|
|
169
|
+
# BTW, 'existing element' means a representation of this element already in memory
|
|
170
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
171
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
172
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
173
|
+
# puts "FOUND AN EXISTING THING... #{ klasses[0] } #{ @attributeValue[i] }"
|
|
174
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
175
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
176
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
177
|
+
# caller(0).each { | trace | puts " #{trace}"}
|
|
178
|
+
# existing_element.reset_contents
|
|
179
|
+
# element = existing_element
|
|
180
|
+
# existing_element = nil
|
|
181
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} EXISTING ELEMENT: #{ existing_element }"
|
|
182
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} WOW, must handle the existing element correctly"
|
|
183
|
+
element = existing_element #TODO -- IS THIS RIGHT????????????????????????
|
|
184
|
+
end
|
|
185
|
+
unless element then
|
|
186
|
+
element = klasses[0].new
|
|
187
|
+
requires_caching = @recovering
|
|
188
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} WOW, what about recovering????"
|
|
189
|
+
#TODO -- IS THIS RIGHT????????????????????????
|
|
190
|
+
requires_caching = true #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
191
|
+
unless @recovering then
|
|
192
|
+
element.force_load if parent
|
|
193
|
+
end
|
|
194
|
+
element.note_created(@is_realising)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
break
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
unless element then
|
|
203
|
+
element = klasses[0].new
|
|
204
|
+
element.note_created(@is_realising)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
element.note_initialise_attributes_with(@attributeName, @attributeNamespace, @attributeValue, @is_realising)
|
|
208
|
+
element.init_attributes(@attributeName, @attributeNamespace, @attributeValue)
|
|
209
|
+
element.note_attributes_initialised(@is_realising)
|
|
210
|
+
|
|
211
|
+
if requires_caching and element and element.persist_required then
|
|
212
|
+
# puts "ELEMENT: #{element}, #{element.class.name}"
|
|
213
|
+
Xampl.cache(element)
|
|
214
|
+
# found = Xampl.find_known(element.class, element.get_the_index)
|
|
215
|
+
# puts "OK? #{found == element} found: #{found}, element: #{element}"
|
|
216
|
+
# puts "=============================================================================="
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
#element = element.note_add_to_parent(parent, @is_realising)
|
|
220
|
+
#element.append_to(parent) if parent
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
while not endDocument?
|
|
224
|
+
case nextEvent
|
|
225
|
+
when START_DOCUMENT
|
|
226
|
+
return element if @recovering
|
|
227
|
+
return existing_element || element
|
|
228
|
+
when END_DOCUMENT
|
|
229
|
+
return element if @recovering
|
|
230
|
+
return existing_element || element
|
|
231
|
+
when START_ELEMENT
|
|
232
|
+
child, ignore_child = parse_element(element)
|
|
233
|
+
unless ignore_child then
|
|
234
|
+
case child
|
|
235
|
+
when XamplObject then
|
|
236
|
+
child = child.note_add_to_parent(element, @is_realising) if child
|
|
237
|
+
child = element.note_add_child(child, @is_realising) if element
|
|
238
|
+
child.append_to(element) if element and child
|
|
239
|
+
when XMLText then
|
|
240
|
+
puts "UNRECOGNISED Well-formed XML: #{child.to_s[0..25]}..."
|
|
241
|
+
else
|
|
242
|
+
puts "WHAT IS THIS??? #{child.class.name}"
|
|
243
|
+
end
|
|
244
|
+
# if child.kind_of? XamplObject then
|
|
245
|
+
# child = child.note_add_to_parent(element, @is_realising) if child
|
|
246
|
+
# child = element.note_add_child(child, @is_realising) if element
|
|
247
|
+
# child.append_to(element) if element and child
|
|
248
|
+
# else
|
|
249
|
+
# puts "WHAT IS THIS??? #{child.class.name}"
|
|
250
|
+
# end
|
|
251
|
+
end
|
|
252
|
+
when END_ELEMENT
|
|
253
|
+
element = element.note_closed(@is_realising)
|
|
254
|
+
return element if @recovering
|
|
255
|
+
return existing_element || element
|
|
256
|
+
when TEXT, CDATA_SECTION, ENTITY_REF
|
|
257
|
+
if element.has_mixed_content then
|
|
258
|
+
the_text = element.note_adding_text_content(@text, @is_realising)
|
|
259
|
+
# element.add_content(the_text, @tokenise_content)
|
|
260
|
+
element << the_text
|
|
261
|
+
# puts "#{__LINE__ }:: add_content [#{the_text}]"
|
|
262
|
+
else
|
|
263
|
+
unless whitespace? then
|
|
264
|
+
the_text = element.note_adding_text_content(@text, @is_realising)
|
|
265
|
+
# 16 Mar 2007 -- this was making preformatted text content impossible
|
|
266
|
+
# element.add_content(the_text, @tokenise_content)
|
|
267
|
+
element.add_content(the_text, false)
|
|
268
|
+
# puts "#{__LINE__ }:: add_content [#{the_text}] --> [#{element.content}]"
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
return element if @recovering
|
|
275
|
+
return existing_element || element
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def next_interesting_event
|
|
279
|
+
if (endDocument?) then
|
|
280
|
+
return Xampl_PP::END_DOCUMENT
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
boring = true
|
|
284
|
+
while boring do
|
|
285
|
+
event = nextEvent
|
|
286
|
+
case event
|
|
287
|
+
when Xampl_PP::START_DOCUMENT
|
|
288
|
+
boring = true
|
|
289
|
+
when Xampl_PP::END_DOCUMENT
|
|
290
|
+
boring = false
|
|
291
|
+
when Xampl_PP::START_ELEMENT
|
|
292
|
+
boring = false
|
|
293
|
+
when Xampl_PP::END_ELEMENT
|
|
294
|
+
boring = false
|
|
295
|
+
when Xampl_PP::TEXT
|
|
296
|
+
boring = false
|
|
297
|
+
when Xampl_PP::CDATA_SECTION
|
|
298
|
+
boring = false
|
|
299
|
+
when Xampl_PP::ENTITY_REF
|
|
300
|
+
boring = false
|
|
301
|
+
when Xampl_PP::IGNORABLE_WHITESPACE
|
|
302
|
+
boring = true
|
|
303
|
+
when Xampl_PP::PROCESSING_INSTRUCTION
|
|
304
|
+
boring = true
|
|
305
|
+
when Xampl_PP::COMMENT
|
|
306
|
+
boring = true
|
|
307
|
+
when Xampl_PP::DOCTYPE
|
|
308
|
+
boring = true
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
return event
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def attributeCount
|
|
315
|
+
return @attributeName.length
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def attributeName(i)
|
|
319
|
+
return @attributeName[i]
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def attributeNamespace(i)
|
|
323
|
+
return @attributeNamespace[i]
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
def attributeQName(i)
|
|
327
|
+
return @attributeQName[i]
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def attributePrefix(i)
|
|
331
|
+
return @attributePrefix[i]
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def attributeValue(i)
|
|
335
|
+
return @attributeValue[i]
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def depth
|
|
339
|
+
return depth
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def line
|
|
343
|
+
return line
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def column
|
|
347
|
+
return column
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
require 'libxml'
|
|
2
|
+
|
|
3
|
+
module Xampl
|
|
4
|
+
|
|
5
|
+
class FromXML
|
|
6
|
+
|
|
7
|
+
attr :checkWellFormed, false
|
|
8
|
+
attr :is_realising, false
|
|
9
|
+
attr :tokenise_content, false
|
|
10
|
+
|
|
11
|
+
@reader = nil
|
|
12
|
+
|
|
13
|
+
@@by_tag = {}
|
|
14
|
+
@@by_ns_tag = {}
|
|
15
|
+
|
|
16
|
+
def initialize(recovering=false)
|
|
17
|
+
@recovering = recovering
|
|
18
|
+
|
|
19
|
+
@attribute_name = Array.new(32)
|
|
20
|
+
@attribute_namespace = Array.new(32)
|
|
21
|
+
@attribute_value = Array.new(32)
|
|
22
|
+
|
|
23
|
+
@insert_end_element = false
|
|
24
|
+
@faking_an_end_element = false
|
|
25
|
+
@just_opened_an_element = false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def FromXML.reset_registry
|
|
29
|
+
@@by_tag = {}
|
|
30
|
+
@@by_ns_tag = {}
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def FromXML.register(tag, ns_tag, klass)
|
|
34
|
+
@@by_ns_tag[ns_tag] = [ klass ]
|
|
35
|
+
a = @@by_tag[tag]
|
|
36
|
+
if (nil == a) then
|
|
37
|
+
@@by_tag[tag] = [ klass ]
|
|
38
|
+
else
|
|
39
|
+
found = false
|
|
40
|
+
a.each { | thing | found = found | (thing == klass) }
|
|
41
|
+
a << klass unless found
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def FromXML.registered(name)
|
|
46
|
+
klass = @@by_ns_tag[name]
|
|
47
|
+
klass = @@by_tag[name] unless klass
|
|
48
|
+
klass = [] unless klass
|
|
49
|
+
return klass
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def resolve(name)
|
|
53
|
+
#TODO -- ???
|
|
54
|
+
return name
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def setup_parse(filename, tokenise_content=true, is_realising=false)
|
|
58
|
+
@resolver = self
|
|
59
|
+
|
|
60
|
+
@is_realising = is_realising
|
|
61
|
+
@tokenise_content = tokenise_content
|
|
62
|
+
|
|
63
|
+
@reader = LibXML::XML::Reader.file(filename,
|
|
64
|
+
:options => LibXML::XML::Parser::Options::NOENT |
|
|
65
|
+
LibXML::XML::Parser::Options::NONET |
|
|
66
|
+
LibXML::XML::Parser::Options::NOCDATA |
|
|
67
|
+
LibXML::XML::Parser::Options::DTDATTR |
|
|
68
|
+
LibXML::XML::Parser::Options::COMPACT)
|
|
69
|
+
#TODO CLOSE THIS THING!!
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def setup_parse_string(string, tokenise_content=true, is_realising=false)
|
|
73
|
+
@resolver = self
|
|
74
|
+
|
|
75
|
+
@is_realising = is_realising
|
|
76
|
+
@tokenise_content = tokenise_content
|
|
77
|
+
|
|
78
|
+
# setInput(string)
|
|
79
|
+
@reader = LibXML::XML::Reader.string(string,
|
|
80
|
+
:options => LibXML::XML::Parser::Options::NOENT |
|
|
81
|
+
LibXML::XML::Parser::Options::NONET |
|
|
82
|
+
LibXML::XML::Parser::Options::NOCDATA |
|
|
83
|
+
LibXML::XML::Parser::Options::DTDATTR |
|
|
84
|
+
LibXML::XML::Parser::Options::COMPACT)
|
|
85
|
+
#TODO CLOSE THIS THING!!
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def parse(filename, tokenise_content=true, is_realising=false)
|
|
89
|
+
begin
|
|
90
|
+
setup_parse(filename, tokenise_content, is_realising)
|
|
91
|
+
element, ignore = parse_element
|
|
92
|
+
return element
|
|
93
|
+
rescue Exception => e
|
|
94
|
+
puts "trouble parsing file: '#{filename}'"
|
|
95
|
+
puts "Exception: #{e}"
|
|
96
|
+
raise
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def realise_string(string, tokenise_content=true, target=nil)
|
|
101
|
+
return parse_string(string, tokenise_content, true, target)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def parse_string(string, tokenise_content=true, is_realising=false, target=nil)
|
|
105
|
+
begin
|
|
106
|
+
setup_parse_string(string, tokenise_content, is_realising)
|
|
107
|
+
element, ignore = parse_element(nil, target)
|
|
108
|
+
return element
|
|
109
|
+
rescue Exception => e
|
|
110
|
+
puts "trouble parsing string: '#{string}'"
|
|
111
|
+
puts "Exception: #{e}"
|
|
112
|
+
raise
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def FromXML.tokenise_string(str, strip=true)
|
|
117
|
+
return nil unless str
|
|
118
|
+
str.strip! if strip
|
|
119
|
+
str.gsub!(/[ \n\r\t][ \n\r\t]*/, " ")
|
|
120
|
+
return str
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def parse_element(parent=nil, target=nil)
|
|
124
|
+
find_the_first_element
|
|
125
|
+
return unless start_element?
|
|
126
|
+
|
|
127
|
+
namespace = @reader.namespace_uri
|
|
128
|
+
name = @reader.local_name
|
|
129
|
+
|
|
130
|
+
existing_element = nil
|
|
131
|
+
element = nil
|
|
132
|
+
|
|
133
|
+
requires_caching = false
|
|
134
|
+
|
|
135
|
+
build_attribute_arrays
|
|
136
|
+
|
|
137
|
+
if ((nil != namespace) and (0 < namespace.size)) then
|
|
138
|
+
klass_name = "{#{namespace}}#{name}"
|
|
139
|
+
klasses = FromXML.registered(klass_name)
|
|
140
|
+
if (0 == klasses.size) then
|
|
141
|
+
xml_text = XMLText.new
|
|
142
|
+
xml_text.build(self)
|
|
143
|
+
xml_text = parent.note_adding_text_content(xml_text, @is_realising)
|
|
144
|
+
parent.add_content(xml_text, @tokenise_content) if xml_text
|
|
145
|
+
return xml_text, false
|
|
146
|
+
end
|
|
147
|
+
if (1 < klasses.size) then
|
|
148
|
+
raise XamplException.new("there is more than one '#{name}' tag in namespace '#{namespace}'\nplease report this error")
|
|
149
|
+
end
|
|
150
|
+
else
|
|
151
|
+
klasses = FromXML.registered(name)
|
|
152
|
+
if (0 == klasses.size) then
|
|
153
|
+
raise XamplException.new("do not recognise tag '#{name}' (no namespace specified)")
|
|
154
|
+
end
|
|
155
|
+
if (1 < klasses.size) then
|
|
156
|
+
raise XamplException.new("there is more than one '#{name}' tag (no namespace specified)")
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
unless @is_realising then
|
|
161
|
+
@attribute_value.size.times do |i|
|
|
162
|
+
FromXML.tokenise_string @attribute_value[i]
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if target then
|
|
167
|
+
element = target
|
|
168
|
+
target.load_needed = false
|
|
169
|
+
target = nil
|
|
170
|
+
element.init_attributes(@attribute_name, @attribute_namespace, @attribute_value)
|
|
171
|
+
element.note_attributes_initialised(@is_realising)
|
|
172
|
+
else
|
|
173
|
+
if klasses[0].persisted? then
|
|
174
|
+
@attribute_name.each_index do |i|
|
|
175
|
+
if @attribute_name[i] == klasses[0].persisted?.to_s then
|
|
176
|
+
existing_element = Xampl.find_known(klasses[0], @attribute_value[i])
|
|
177
|
+
if existing_element then
|
|
178
|
+
# so we've found the element. Now what??? We can do several
|
|
179
|
+
# reasonable things:
|
|
180
|
+
#
|
|
181
|
+
# 1) continue parsing into the found element
|
|
182
|
+
# 2) simply return the found element
|
|
183
|
+
# 3) replace the found element with the new element
|
|
184
|
+
#
|
|
185
|
+
# The first one is dubious, so we won't.
|
|
186
|
+
# The second and third option both make complete sense
|
|
187
|
+
#
|
|
188
|
+
# We are going to do the second
|
|
189
|
+
#
|
|
190
|
+
# BTW, 'existing element' means a representation of this element already in memory
|
|
191
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
192
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
193
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
194
|
+
# puts "FOUND AN EXISTING THING... #{ klasses[0] } #{ @attribute_value[i] }"
|
|
195
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
196
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
197
|
+
# puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
|
198
|
+
# caller(0).each { | trace | puts " #{trace}"}
|
|
199
|
+
# existing_element.reset_contents
|
|
200
|
+
# element = existing_element
|
|
201
|
+
# existing_element = nil
|
|
202
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} EXISTING ELEMENT: #{ existing_element }"
|
|
203
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} WOW, must handle the existing element correctly"
|
|
204
|
+
element = existing_element #TODO -- IS THIS RIGHT????????????????????????
|
|
205
|
+
end
|
|
206
|
+
unless element then
|
|
207
|
+
element = klasses[0].new
|
|
208
|
+
requires_caching = @recovering
|
|
209
|
+
# puts "#{File.basename(__FILE__)} #{__LINE__} WOW, what about recovering????"
|
|
210
|
+
#TODO -- IS THIS RIGHT????????????????????????
|
|
211
|
+
requires_caching = true #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
212
|
+
unless @recovering then
|
|
213
|
+
element.force_load if parent
|
|
214
|
+
end
|
|
215
|
+
element.note_created(@is_realising)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
break
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
unless element then
|
|
224
|
+
element = klasses[0].new
|
|
225
|
+
element.note_created(@is_realising)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
element.note_initialise_attributes_with(@attribute_name, @attribute_namespace, @attribute_value, @is_realising)
|
|
229
|
+
element.init_attributes(@attribute_name, @attribute_namespace, @attribute_value)
|
|
230
|
+
element.note_attributes_initialised(@is_realising)
|
|
231
|
+
|
|
232
|
+
if requires_caching and element and element.persist_required then
|
|
233
|
+
Xampl.cache(element)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
#element = element.note_add_to_parent(parent, @is_realising)
|
|
237
|
+
#element.append_to(parent) if parent
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
while next_reader_event
|
|
241
|
+
case current_node_type
|
|
242
|
+
|
|
243
|
+
=begin
|
|
244
|
+
TODO -- can these ever happen?
|
|
245
|
+
when START_DOCUMENT
|
|
246
|
+
return element if @recovering
|
|
247
|
+
return existing_element || element
|
|
248
|
+
when END_DOCUMENT
|
|
249
|
+
return element if @recovering
|
|
250
|
+
return existing_element || element
|
|
251
|
+
|
|
252
|
+
=end
|
|
253
|
+
|
|
254
|
+
when LibXML::XML::Reader::TYPE_ELEMENT
|
|
255
|
+
child, ignore_child = parse_element(element)
|
|
256
|
+
|
|
257
|
+
unless ignore_child then
|
|
258
|
+
case child
|
|
259
|
+
when XamplObject then
|
|
260
|
+
child = child.note_add_to_parent(element, @is_realising) if child
|
|
261
|
+
child = element.note_add_child(child, @is_realising) if element
|
|
262
|
+
child.append_to(element) if element and child
|
|
263
|
+
when XMLText then
|
|
264
|
+
puts "UNRECOGNISED Well-formed XML: #{child.to_s[0..25]}..."
|
|
265
|
+
else
|
|
266
|
+
puts "WHAT IS THIS??? #{child.class.name}"
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
when LibXML::XML::Reader::TYPE_END_ELEMENT
|
|
270
|
+
element = element.note_closed(@is_realising)
|
|
271
|
+
return element if @recovering
|
|
272
|
+
return existing_element || element
|
|
273
|
+
when LibXML::XML::Reader::TYPE_TEXT, LibXML::XML::Reader::TYPE_CDATA, LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE, LibXML::XML::Reader::TYPE_ENTITY_REFERENCE
|
|
274
|
+
if element.has_mixed_content then
|
|
275
|
+
text = @reader.read_string
|
|
276
|
+
the_text = element.note_adding_text_content(text, @is_realising)
|
|
277
|
+
element << the_text
|
|
278
|
+
else
|
|
279
|
+
text = @reader.read_string
|
|
280
|
+
the_text = element.note_adding_text_content(text, @is_realising)
|
|
281
|
+
element.add_content(the_text, false)
|
|
282
|
+
end
|
|
283
|
+
else
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
return element if @recovering
|
|
288
|
+
return existing_element || element
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def current_node_type
|
|
292
|
+
if @faking_an_end_element then
|
|
293
|
+
LibXML::XML::Reader::TYPE_END_ELEMENT
|
|
294
|
+
else
|
|
295
|
+
@reader.node_type
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
=begin
|
|
300
|
+
def describe_current_element_type()
|
|
301
|
+
case @reader.node_type
|
|
302
|
+
when LibXML::XML::Reader::TYPE_ATTRIBUTE
|
|
303
|
+
puts "ATTRIBUTE"
|
|
304
|
+
when LibXML::XML::Reader::TYPE_DOCUMENT
|
|
305
|
+
puts "DOCUMENT"
|
|
306
|
+
when LibXML::XML::Reader::TYPE_ELEMENT
|
|
307
|
+
attribute_count = @reader.attribute_count
|
|
308
|
+
puts "ELEMENT #{ @reader.local_name }, ns: #{ @reader.namespace_uri }, #attributes: #{ attribute_count }, depth: #{ @reader.depth }"
|
|
309
|
+
puts " FAKING END ELEMENT" if @faking_an_end_element
|
|
310
|
+
when LibXML::XML::Reader::TYPE_END_ELEMENT
|
|
311
|
+
puts "END ELEMENT"
|
|
312
|
+
when LibXML::XML::Reader::TYPE_TEXT
|
|
313
|
+
puts "TEXT [[#{ @reader.read_string }]]"
|
|
314
|
+
when LibXML::XML::Reader::TYPE_CDATA
|
|
315
|
+
puts "CDATA [[#{ @reader.read_string }]]"
|
|
316
|
+
when LibXML::XML::Reader::TYPE_SIGNIFICANT_WHITESPACE
|
|
317
|
+
puts "SIGNIFICANT white space [[#{ @reader.read_string }]]"
|
|
318
|
+
when LibXML::XML::Reader::TYPE_ENTITY_REFERENCE
|
|
319
|
+
puts "entity ref"
|
|
320
|
+
when LibXML::XML::Reader::TYPE_WHITESPACE
|
|
321
|
+
puts "whitespace"
|
|
322
|
+
when LibXML::XML::Reader::TYPE_PROCESSING_INSTRUCTION
|
|
323
|
+
puts "processing instruction"
|
|
324
|
+
when LibXML::XML::Reader::TYPE_COMMENT
|
|
325
|
+
puts "comment"
|
|
326
|
+
when LibXML::XML::Reader::TYPE_DOCUMENT_TYPE
|
|
327
|
+
puts "doc type"
|
|
328
|
+
|
|
329
|
+
when LibXML::XML::Reader::TYPE_XML_DECLARATION
|
|
330
|
+
puts "xml decl"
|
|
331
|
+
when LibXML::XML::Reader::TYPE_NONE
|
|
332
|
+
puts "NONE!!"
|
|
333
|
+
when LibXML::XML::Reader::TYPE_NOTATION
|
|
334
|
+
puts "notifiation"
|
|
335
|
+
when LibXML::XML::Reader::TYPE_DOCUMENT_FRAGMENT
|
|
336
|
+
puts "doc fragment"
|
|
337
|
+
when LibXML::XML::Reader::TYPE_ENTITY
|
|
338
|
+
puts "entity"
|
|
339
|
+
when LibXML::XML::Reader::TYPE_END_ENTITY
|
|
340
|
+
puts "end entity"
|
|
341
|
+
else
|
|
342
|
+
puts "UNKNOWN: #{@reader.node_type}"
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
=end
|
|
346
|
+
|
|
347
|
+
def next_reader_event
|
|
348
|
+
if @insert_end_element then
|
|
349
|
+
@faking_an_end_element = true
|
|
350
|
+
@insert_end_element = false
|
|
351
|
+
return
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
@faking_an_end_element = false
|
|
355
|
+
|
|
356
|
+
#describe_current_element_type
|
|
357
|
+
|
|
358
|
+
okay = @reader.read
|
|
359
|
+
|
|
360
|
+
@just_opened_an_element = start_element?
|
|
361
|
+
@insert_end_element = (@just_opened_an_element and @reader.empty_element?)
|
|
362
|
+
|
|
363
|
+
#describe_current_element_type
|
|
364
|
+
|
|
365
|
+
okay
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
def start_element?
|
|
369
|
+
current_node_type == LibXML::XML::Reader::TYPE_ELEMENT
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
def whitespace?
|
|
373
|
+
current_note_type == LibXML::XML::Reader::TYPE_WHITESPACE
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def find_the_first_element
|
|
377
|
+
while true do
|
|
378
|
+
break if start_element?
|
|
379
|
+
break unless next_reader_event
|
|
380
|
+
end
|
|
381
|
+
@just_opened_an_element = start_element?
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
def build_attribute_arrays
|
|
385
|
+
|
|
386
|
+
@attribute_name.clear
|
|
387
|
+
@attribute_namespace.clear
|
|
388
|
+
@attribute_value.clear
|
|
389
|
+
|
|
390
|
+
return unless LibXML::XML::Reader::TYPE_ELEMENT == current_node_type
|
|
391
|
+
|
|
392
|
+
if @reader.has_attributes? then
|
|
393
|
+
attribute_count = @reader.attribute_count
|
|
394
|
+
@reader.move_to_first_attribute
|
|
395
|
+
attribute_count.times do | i |
|
|
396
|
+
if @reader.namespace_declaration? then
|
|
397
|
+
@reader.move_to_next_attribute
|
|
398
|
+
next
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
@attribute_name << @reader.local_name
|
|
402
|
+
@attribute_namespace << @reader.namespace_uri
|
|
403
|
+
@attribute_value << @reader.value
|
|
404
|
+
|
|
405
|
+
@reader.move_to_next_attribute
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def attributeCount
|
|
411
|
+
return @attribute_name.length
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
def attributeName(i)
|
|
415
|
+
return @attribute_name[i]
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def attributeNamespace(i)
|
|
419
|
+
return @attribute_namespace[i]
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def attributeValue(i)
|
|
423
|
+
return @attribute_value[i]
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
def depth
|
|
427
|
+
return @reader.depth
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def line
|
|
431
|
+
return @reader.line_number
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
def column
|
|
435
|
+
return @reader.column_number
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
end
|