Class: Moxml::Adapter::Rexml
- Inherits:
-
Base
- Object
- Base
- Moxml::Adapter::Rexml
show all
- Defined in:
- lib/moxml/adapter/rexml.rb
Class Method Summary
collapse
-
.add_child(element, child) ⇒ Object
-
.add_next_sibling(node, sibling) ⇒ Object
-
.add_previous_sibling(node, sibling) ⇒ Object
-
.at_xpath(node, expression, namespaces = {}) ⇒ Object
-
.attribute_element(attribute) ⇒ Object
-
.attributes(element) ⇒ Object
-
.cdata_content(node) ⇒ Object
-
.children(node) ⇒ Object
-
.comment_content(node) ⇒ Object
-
.create_document ⇒ Object
-
.create_native_cdata(content) ⇒ Object
-
.create_native_comment(content) ⇒ Object
-
.create_native_declaration(version, encoding, standalone) ⇒ Object
-
.create_native_doctype(name, external_id, system_id) ⇒ Object
-
.create_native_element(name) ⇒ Object
-
.create_native_namespace(element, prefix, uri) ⇒ Object
add a namespace definition, keep the element name unchanged.
-
.create_native_processing_instruction(target, content) ⇒ Object
-
.create_native_text(content) ⇒ Object
-
.declaration_attribute(node, name) ⇒ Object
-
.document(node) ⇒ Object
-
.duplicate_node(node) ⇒ Object
-
.get_attribute(element, name) ⇒ Object
-
.get_attribute_value(element, name) ⇒ Object
-
.inner_text(node) ⇒ Object
-
.namespace(node) ⇒ Object
-
.namespace_definitions(node) ⇒ Object
-
.namespace_prefix(node) ⇒ Object
-
.namespace_uri(node) ⇒ Object
-
.next_sibling(node) ⇒ Object
-
.node_name(node) ⇒ Object
-
.node_type(node) ⇒ Object
-
.parent(node) ⇒ Object
-
.parse(xml, options = {}) ⇒ Object
-
.prepare_xpath_namespaces(node) ⇒ Object
-
.previous_sibling(node) ⇒ Object
-
.processing_instruction_content(node) ⇒ Object
-
.processing_instruction_target(node) ⇒ Object
-
.remove(node) ⇒ Object
-
.remove_attribute(element, name) ⇒ Object
-
.replace(node, new_node) ⇒ Object
-
.replace_children(element, children) ⇒ Object
-
.root(document) ⇒ Object
-
.serialize(node, options = {}) ⇒ Object
-
.set_attribute(element, name, value) ⇒ Object
-
.set_attribute_name(attribute, name) ⇒ Object
-
.set_attribute_value(attribute, value) ⇒ Object
-
.set_cdata_content(node, content) ⇒ Object
-
.set_comment_content(node, content) ⇒ Object
-
.set_declaration_attribute(node, name, value) ⇒ Object
-
.set_namespace(element, ns) ⇒ Object
add a namespace prefix to the element name AND a namespace definition.
-
.set_node_name(node, name) ⇒ Object
-
.set_processing_instruction_content(node, content) ⇒ Object
-
.set_root(doc, element) ⇒ Object
-
.set_text_content(node, content) ⇒ Object
-
.text_content(node) ⇒ Object
-
.xpath(node, expression, _namespaces = {}) ⇒ Object
Methods inherited from Base
create_cdata, create_comment, create_declaration, create_doctype, create_element, create_namespace, create_processing_instruction, create_text
Methods included from XmlUtils
#encode_entities, #normalize_xml_value, #validate_comment_content, #validate_declaration_encoding, #validate_declaration_standalone, #validate_declaration_version, #validate_element_name, #validate_pi_target, #validate_prefix, #validate_uri
Class Method Details
.add_child(element, child) ⇒ Object
227
228
229
230
231
232
233
234
|
# File 'lib/moxml/adapter/rexml.rb', line 227
def add_child(element, child)
case child
when String
element.add_text(child)
else
element.add(child)
end
end
|
.add_next_sibling(node, sibling) ⇒ Object
246
247
248
249
|
# File 'lib/moxml/adapter/rexml.rb', line 246
def add_next_sibling(node, sibling)
parent = node.parent
parent.insert_after(node, sibling)
end
|
.add_previous_sibling(node, sibling) ⇒ Object
236
237
238
239
240
241
242
243
244
|
# File 'lib/moxml/adapter/rexml.rb', line 236
def add_previous_sibling(node, sibling)
parent = node.parent
parent.insert_before(node, sibling)
end
|
.at_xpath(node, expression, namespaces = {}) ⇒ Object
407
408
409
410
|
# File 'lib/moxml/adapter/rexml.rb', line 407
def at_xpath(node, expression, namespaces = {})
results = xpath(node, expression, namespaces)
results.first
end
|
.attribute_element(attribute) ⇒ Object
193
194
195
|
# File 'lib/moxml/adapter/rexml.rb', line 193
def attribute_element(attribute)
attribute.element
end
|
.attributes(element) ⇒ Object
185
186
187
188
189
190
191
|
# File 'lib/moxml/adapter/rexml.rb', line 185
def attributes(element)
return [] unless element.respond_to?(:attributes)
element.attributes.values
.reject { |attr| attr.prefix.to_s.start_with?("xmlns") }
end
|
.cdata_content(node) ⇒ Object
294
295
296
|
# File 'lib/moxml/adapter/rexml.rb', line 294
def cdata_content(node)
node.value
end
|
.children(node) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/moxml/adapter/rexml.rb', line 111
def children(node)
return [] unless node.respond_to?(:children)
result = node.children.reject do |child|
child.is_a?(::REXML::Text) &&
child.to_s.strip.empty? &&
!(child.next_sibling.nil? && child.previous_sibling.nil?)
end
result.uniq(&:object_id)
end
|
286
287
288
|
# File 'lib/moxml/adapter/rexml.rb', line 286
def (node)
node.string
end
|
.create_document ⇒ Object
24
25
26
|
# File 'lib/moxml/adapter/rexml.rb', line 24
def create_document
::REXML::Document.new
end
|
.create_native_cdata(content) ⇒ Object
36
37
38
|
# File 'lib/moxml/adapter/rexml.rb', line 36
def create_native_cdata(content)
::REXML::CData.new(content.to_s)
end
|
40
41
42
|
# File 'lib/moxml/adapter/rexml.rb', line 40
def (content)
::REXML::Comment.new(content.to_s)
end
|
.create_native_declaration(version, encoding, standalone) ⇒ Object
49
50
51
|
# File 'lib/moxml/adapter/rexml.rb', line 49
def create_native_declaration(version, encoding, standalone)
::REXML::XMLDecl.new(version, encoding&.downcase, standalone)
end
|
.create_native_doctype(name, external_id, system_id) ⇒ Object
53
54
55
56
57
58
59
60
61
62
63
64
65
|
# File 'lib/moxml/adapter/rexml.rb', line 53
def create_native_doctype(name, external_id, system_id)
return nil unless name
parts = [name]
if external_id
parts.concat(["PUBLIC", %("#{external_id}")])
parts << %("#{system_id}") if system_id
elsif system_id
parts.concat(["SYSTEM", %("#{system_id}")])
end
::REXML::DocType.new(parts.join(" "))
end
|
.create_native_element(name) ⇒ Object
28
29
30
|
# File 'lib/moxml/adapter/rexml.rb', line 28
def create_native_element(name)
::REXML::Element.new(name.to_s)
end
|
.create_native_namespace(element, prefix, uri) ⇒ Object
add a namespace definition, keep the element name unchanged
346
347
348
349
|
# File 'lib/moxml/adapter/rexml.rb', line 346
def create_native_namespace(element, prefix, uri)
element.add_namespace(prefix.to_s, uri)
::REXML::Attribute.new(prefix.to_s, uri, element)
end
|
.create_native_processing_instruction(target, content) ⇒ Object
44
45
46
47
|
# File 'lib/moxml/adapter/rexml.rb', line 44
def create_native_processing_instruction(target, content)
::REXML::Instruction.new(target.to_s.dup, content.to_s.dup)
end
|
.create_native_text(content) ⇒ Object
32
33
34
|
# File 'lib/moxml/adapter/rexml.rb', line 32
def create_native_text(content)
::REXML::Text.new(content.to_s, true, nil)
end
|
.declaration_attribute(node, name) ⇒ Object
264
265
266
267
268
269
270
271
272
273
|
# File 'lib/moxml/adapter/rexml.rb', line 264
def declaration_attribute(node, name)
case name
when "version"
node.version
when "encoding"
node.encoding
when "standalone"
node.standalone
end
end
|
.document(node) ⇒ Object
177
178
179
|
# File 'lib/moxml/adapter/rexml.rb', line 177
def document(node)
node.document
end
|
.duplicate_node(node) ⇒ Object
105
106
107
108
109
|
# File 'lib/moxml/adapter/rexml.rb', line 105
def duplicate_node(node)
Marshal.load(Marshal.dump(node))
end
|
.get_attribute(element, name) ⇒ Object
215
216
217
|
# File 'lib/moxml/adapter/rexml.rb', line 215
def get_attribute(element, name)
element.attributes.get_attribute(name)
end
|
.get_attribute_value(element, name) ⇒ Object
219
220
221
|
# File 'lib/moxml/adapter/rexml.rb', line 219
def get_attribute_value(element, name)
element.attributes[name]
end
|
.inner_text(node) ⇒ Object
325
326
327
328
329
330
331
|
# File 'lib/moxml/adapter/rexml.rb', line 325
def inner_text(node)
text_children = node.children
.select { |c| c.is_a?(::REXML::Text) }
.uniq(&:object_id)
text_children.map(&:value).join
end
|
.namespace(node) ⇒ Object
368
369
370
371
372
373
374
375
|
# File 'lib/moxml/adapter/rexml.rb', line 368
def namespace(node)
prefix = node.prefix
uri = node.namespace(prefix)
return if prefix.to_s.empty? && uri.to_s.empty?
owner = node.is_a?(::REXML::Attribute) ? node.element : node
::REXML::Attribute.new(prefix, uri, owner)
end
|
.namespace_definitions(node) ⇒ Object
377
378
379
380
381
|
# File 'lib/moxml/adapter/rexml.rb', line 377
def namespace_definitions(node)
node.namespaces.map do |prefix, uri|
::REXML::Attribute.new(prefix.to_s, uri, node)
end
end
|
.namespace_prefix(node) ⇒ Object
360
361
362
|
# File 'lib/moxml/adapter/rexml.rb', line 360
def namespace_prefix(node)
node.name unless node.name == "xmlns"
end
|
.namespace_uri(node) ⇒ Object
364
365
366
|
# File 'lib/moxml/adapter/rexml.rb', line 364
def namespace_uri(node)
node.value
end
|
.next_sibling(node) ⇒ Object
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# File 'lib/moxml/adapter/rexml.rb', line 129
def next_sibling(node)
current = node.next_sibling
seen = Set.new
while current
if current.is_a?(::REXML::Text) && current.to_s.strip.empty?
current = current.next_sibling
next
end
if seen.include?(current.object_id)
current = current.next_sibling
next
end
seen.add(current.object_id)
break
end
current
end
|
.node_name(node) ⇒ Object
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/moxml/adapter/rexml.rb', line 94
def node_name(node)
case node
when ::REXML::Element, ::REXML::DocType
node.name
when ::REXML::XMLDecl
"xml"
when ::REXML::Instruction
node.target
end
end
|
.node_type(node) ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/moxml/adapter/rexml.rb', line 71
def node_type(node)
case node
when ::REXML::Document then :document
when ::REXML::Element then :element
when ::REXML::CData then :cdata
when ::REXML::Text then :text
when ::REXML::Comment then :comment
when ::REXML::Instruction then :processing_instruction
when ::REXML::DocType then :doctype
when ::REXML::XMLDecl then :declaration
else :unknown
end
end
|
.parent(node) ⇒ Object
125
126
127
|
# File 'lib/moxml/adapter/rexml.rb', line 125
def parent(node)
node.parent
end
|
.parse(xml, options = {}) ⇒ Object
13
14
15
16
17
18
19
20
21
22
|
# File 'lib/moxml/adapter/rexml.rb', line 13
def parse(xml, options = {})
native_doc = begin
::REXML::Document.new(xml)
rescue ::REXML::ParseException => e
raise Moxml::ParseError.new(e.message, line: e.line) if options[:strict]
create_document
end
DocumentBuilder.new(Context.new(:rexml)).build(native_doc)
end
|
.prepare_xpath_namespaces(node) ⇒ Object
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
|
# File 'lib/moxml/adapter/rexml.rb', line 383
def prepare_xpath_namespaces(node)
ns = {}
all_ns = namespace_definitions(node)
all_ns.each do |prefix, uri|
if prefix.to_s.empty?
ns["xmlns"] = uri
else
ns[prefix] = uri
end
end
ns
end
|
.previous_sibling(node) ⇒ Object
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/moxml/adapter/rexml.rb', line 153
def previous_sibling(node)
current = node.previous_sibling
seen = Set.new
while current
if current.is_a?(::REXML::Text) && current.to_s.strip.empty?
current = current.previous_sibling
next
end
if seen.include?(current.object_id)
current = current.previous_sibling
next
end
seen.add(current.object_id)
break
end
current
end
|
.processing_instruction_content(node) ⇒ Object
306
307
308
|
# File 'lib/moxml/adapter/rexml.rb', line 306
def processing_instruction_content(node)
node.content
end
|
.processing_instruction_target(node) ⇒ Object
302
303
304
|
# File 'lib/moxml/adapter/rexml.rb', line 302
def processing_instruction_target(node)
node.target
end
|
.remove(node) ⇒ Object
251
252
253
|
# File 'lib/moxml/adapter/rexml.rb', line 251
def remove(node)
node.remove
end
|
.remove_attribute(element, name) ⇒ Object
223
224
225
|
# File 'lib/moxml/adapter/rexml.rb', line 223
def remove_attribute(element, name)
element.delete_attribute(name.to_s)
end
|
.replace(node, new_node) ⇒ Object
255
256
257
|
# File 'lib/moxml/adapter/rexml.rb', line 255
def replace(node, new_node)
node.replace_with(new_node)
end
|
.replace_children(element, children) ⇒ Object
259
260
261
262
|
# File 'lib/moxml/adapter/rexml.rb', line 259
def replace_children(element, children)
element.children.each(&:remove)
children.each { |child| element.add(child) }
end
|
.root(document) ⇒ Object
181
182
183
|
# File 'lib/moxml/adapter/rexml.rb', line 181
def root(document)
document.root
end
|
.serialize(node, options = {}) ⇒ Object
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
|
# File 'lib/moxml/adapter/rexml.rb', line 412
def serialize(node, options = {})
output = String.new
if node.is_a?(::REXML::Document)
decl = node.xml_decl || ::REXML::XMLDecl.new("1.0", options[:encoding] || "UTF-8")
decl.encoding = options[:encoding] if options[:encoding]
output << "<?xml"
output << %( version="#{decl.version}") if decl.version
output << %( encoding="#{decl.encoding}") if decl.encoding
output << %( standalone="#{decl.standalone}") if decl.standalone
output << "?>"
if node.doctype
node.doctype.write(output)
end
node.children.each do |child|
if child.is_a?(::REXML::Instruction)
child.write(output)
end
end
write_with_formatter(node.root, output, options[:indent] || 2) if node.root
else
write_with_formatter(node, output, options[:indent] || 2)
end
output.strip
end
|
.set_attribute(element, name, value) ⇒ Object
197
198
199
200
|
# File 'lib/moxml/adapter/rexml.rb', line 197
def set_attribute(element, name, value)
element.attributes[name&.to_s] = value
::REXML::Attribute.new(name&.to_s, value.to_s, element)
end
|
.set_attribute_name(attribute, name) ⇒ Object
202
203
204
205
206
207
208
209
|
# File 'lib/moxml/adapter/rexml.rb', line 202
def set_attribute_name(attribute, name)
old_name = attribute.expanded_name
attribute.name = name
element = attribute.element
element.attributes.delete(old_name)
element.attributes << attribute
end
|
.set_attribute_value(attribute, value) ⇒ Object
211
212
213
|
# File 'lib/moxml/adapter/rexml.rb', line 211
def set_attribute_value(attribute, value)
attribute.normalized = value
end
|
.set_cdata_content(node, content) ⇒ Object
298
299
300
|
# File 'lib/moxml/adapter/rexml.rb', line 298
def set_cdata_content(node, content)
node.value = content.to_s
end
|
290
291
292
|
# File 'lib/moxml/adapter/rexml.rb', line 290
def (node, content)
node.string = content.to_s
end
|
.set_declaration_attribute(node, name, value) ⇒ Object
275
276
277
278
279
280
281
282
283
284
|
# File 'lib/moxml/adapter/rexml.rb', line 275
def set_declaration_attribute(node, name, value)
case name
when "version"
node.version = value
when "encoding"
node.encoding = value
when "standalone"
node.standalone = value
end
end
|
.set_namespace(element, ns) ⇒ Object
add a namespace prefix to the element name AND a namespace definition
352
353
354
355
356
357
358
|
# File 'lib/moxml/adapter/rexml.rb', line 352
def set_namespace(element, ns)
prefix = ns.name.to_s.empty? ? "xmlns" : ns.name.to_s
element.add_namespace(prefix, ns.value) if element.respond_to?(:add_namespace)
element.name = "#{prefix}:#{element.name}"
owner = element.is_a?(::REXML::Attribute) ? element.element : element
::REXML::Attribute.new(prefix, ns.value, owner)
end
|
.set_node_name(node, name) ⇒ Object
85
86
87
88
89
90
91
92
|
# File 'lib/moxml/adapter/rexml.rb', line 85
def set_node_name(node, name)
case node
when ::REXML::Element
node.name = name.to_s
when ::REXML::Instruction
node.target = name.to_s
end
end
|
.set_processing_instruction_content(node, content) ⇒ Object
310
311
312
|
# File 'lib/moxml/adapter/rexml.rb', line 310
def set_processing_instruction_content(node, content)
node.content = content.to_s
end
|
.set_root(doc, element) ⇒ Object
67
68
69
|
# File 'lib/moxml/adapter/rexml.rb', line 67
def set_root(doc, element)
doc.add_element(element)
end
|
.set_text_content(node, content) ⇒ Object
333
334
335
336
337
338
339
340
341
342
343
|
# File 'lib/moxml/adapter/rexml.rb', line 333
def set_text_content(node, content)
case node
when ::REXML::Text, ::REXML::CData
node.value = content.to_s
when ::REXML::Element
node.texts.each(&:remove)
node.add_text(content.to_s)
end
end
|
.text_content(node) ⇒ Object
314
315
316
317
318
319
320
321
322
323
|
# File 'lib/moxml/adapter/rexml.rb', line 314
def text_content(node)
case node
when ::REXML::Text, ::REXML::CData
node.value.to_s
when ::REXML::Element
text_nodes = node.texts.uniq(&:object_id)
text_nodes.map(&:value).join
end
end
|
.xpath(node, expression, _namespaces = {}) ⇒ Object
401
402
403
404
405
|
# File 'lib/moxml/adapter/rexml.rb', line 401
def xpath(node, expression, _namespaces = {})
node.get_elements(expression).to_a
rescue ::REXML::ParseException => e
raise Moxml::XPathError, e.message
end
|