Class: Moxml::Adapter::Ox
- Inherits:
-
Base
- Object
- Base
- Moxml::Adapter::Ox
show all
- Defined in:
- lib/moxml/adapter/ox.rb
Class Method Summary
collapse
-
.add_child(element, child) ⇒ Object
-
.add_next_sibling(node, sibling) ⇒ Object
-
.add_previous_sibling(node, sibling) ⇒ Object
-
.ancestors(node) ⇒ Object
-
.assign_parents(node, parent = nil) ⇒ Object
-
.at_xpath(node, expression, namespaces = {}) ⇒ Object
-
.attachments ⇒ Object
-
.attribute_element(attribute) ⇒ Object
-
.attributes(element) ⇒ Object
-
.cdata_content(node) ⇒ Object
-
.children(node) ⇒ Object
-
.comment_content(node) ⇒ Object
-
.context_adapter_name ⇒ Object
Adapter name used when wrapping bare native nodes; kept overridable so HeadedOx wraps into its own adapter.
-
.create_document(native_doc = nil) ⇒ Object
-
.create_native_cdata(content, _owner_doc = nil) ⇒ Object
-
.create_native_comment(content, _owner_doc = nil) ⇒ Object
-
.create_native_declaration(version, encoding, standalone) ⇒ Object
-
.create_native_doctype(name, external_id, system_id) ⇒ Object
-
.create_native_element(name, _owner_doc = nil) ⇒ Object
-
.create_native_entity_reference(name) ⇒ Object
-
.create_native_namespace(element, prefix, uri) ⇒ Object
-
.create_native_processing_instruction(target, content) ⇒ Object
-
.create_native_text(content, _owner_doc = nil) ⇒ Object
-
.declaration_attribute(declaration, attr_name) ⇒ Object
-
.dedupe_natives(natives) ⇒ Object
Identity-based dedup: uniq's value equality would collapse equal String text nodes.
-
.doctype_external_id(native) ⇒ Object
-
.doctype_name(native) ⇒ Object
Doctype accessor methods Ox stores DOCTYPE as a string, so we parse it.
-
.doctype_system_id(native) ⇒ Object
-
.document(node) ⇒ Object
-
.duplicate_node(node) ⇒ Object
-
.entity_reference_name(node) ⇒ Object
-
.get_attribute(element, name) ⇒ Object
-
.get_attribute_value(element, name) ⇒ Object
-
.has_declaration?(native_doc, _wrapper) ⇒ Boolean
-
.inner_text(node) ⇒ Object
-
.namespace(element) ⇒ Object
-
.namespace_definitions(node) ⇒ Object
-
.namespace_prefix(namespace) ⇒ Object
-
.namespace_uri(namespace) ⇒ Object
-
.needs_custom_serialize?(node) ⇒ Boolean
-
.next_sibling(node) ⇒ Object
-
.node_name(node) ⇒ Object
-
.node_type(node) ⇒ Object
-
.parent(node) ⇒ Object
-
.parse(xml, options = {}, _context = nil) ⇒ Object
-
.patch_node(node, parent = nil) ⇒ Object
-
.patches_children? ⇒ Boolean
-
.previous_sibling(node) ⇒ Object
-
.processing_instruction_content(node) ⇒ Object
-
.processing_instruction_target(node) ⇒ Object
-
.remove(node) ⇒ Object
-
.remove_attribute(element, name) ⇒ Object
-
.remove_attribute_native(attribute) ⇒ Object
-
.remove_declaration(native_doc) ⇒ Object
-
.replace(node, new_node) ⇒ Object
-
.replace_children(node, new_children) ⇒ Object
-
.root(document) ⇒ Object
-
.sax_parse(xml, handler) ⇒ void
SAX parsing implementation for Ox.
-
.serialize(node, options = {}) ⇒ Object
-
.set_attribute(element, name, value) ⇒ Object
-
.set_attribute_name(attribute, name) ⇒ Object
-
.set_attribute_value(attribute, new_value) ⇒ Object
-
.set_cdata_content(node, content) ⇒ Object
-
.set_comment_content(node, content) ⇒ Object
-
.set_declaration_attribute(declaration, attr_name, value) ⇒ Object
-
.set_namespace(element, ns) ⇒ Object
-
.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
-
.tree_scan_custom_needs(node) ⇒ Object
Single walk collecting both custom-serialize triggers.
-
.unpatch_node(node) ⇒ Object
-
.validate_single_root(document) ⇒ Object
-
.xpath(node, expression, namespaces = {}) ⇒ Object
XPath runs through Moxml's pure-Ruby XPath 1.0 engine (shared with HeadedOx and Leptris).
-
.xpath_supported? ⇒ Boolean
Methods inherited from Base
actual_native, attribute_name, bulk_materialize?, create_cdata, create_comment, create_declaration, create_doctype, create_element, create_entity_reference, create_namespace, create_processing_instruction, create_text, decode_entities, entity_bearing?, in_scope_namespaces, line_number, preprocess_entities, restore_entities, sax_supported?, wrappers_recyclable?
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_entity_reference_name, #validate_pi_target, #validate_prefix, #validate_uri
Class Method Details
.add_child(element, child) ⇒ Object
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
446
447
448
449
450
|
# File 'lib/moxml/adapter/ox.rb', line 414
def add_child(element, child)
if element.is_a?(::Ox::Document) && child.is_a?(::Ox::Instruct) && child.target == "xml"
element.attributes ||= {}
element.attributes[:version] = child.attributes["version"] if child.attributes["version"]
element.attributes[:encoding] = child.attributes["encoding"] if child.attributes["encoding"]
element.attributes[:standalone] = child.attributes["standalone"] if child.attributes["standalone"]
attachments.set(element, :decl_explicit, {
encoding: child.attributes.key?("encoding") ? child.attributes["encoding"] : nil,
standalone: child.attributes.key?("standalone") ? child.attributes["standalone"] : nil,
})
return
end
child.parent = element if child.is_a?(::Ox::Node)
element.nodes ||= []
if element.is_a?(::Ox::Document) && child.is_a?(::Ox::DocType)
root_idx = element.nodes.index { |n| n.is_a?(::Ox::Element) }
if root_idx
element.nodes.insert(root_idx, child)
else
element.nodes << child
end
else
element.nodes << child
end
if child.is_a?(::Moxml::Adapter::CustomizedOx::EntityReference)
root = element
while root.is_a?(::Ox::Node) && root.parent
root = root.parent
end
attachments.set(root, :has_entity_refs, true) if root
end
end
|
.add_next_sibling(node, sibling) ⇒ Object
463
464
465
466
467
468
469
470
471
472
|
# File 'lib/moxml/adapter/ox.rb', line 463
def add_next_sibling(node, sibling)
return unless (parent = parent(node))
if sibling.is_a?(::Ox::Node)
sibling.parent&.nodes&.delete(sibling)
sibling.parent = parent
end
idx = parent.nodes.index(node)
parent.nodes.insert(idx + 1, sibling) if idx
end
|
.add_previous_sibling(node, sibling) ⇒ Object
452
453
454
455
456
457
458
459
460
461
|
# File 'lib/moxml/adapter/ox.rb', line 452
def add_previous_sibling(node, sibling)
return unless (parent = parent(node))
if sibling.is_a?(::Ox::Node)
sibling.parent&.nodes&.delete(sibling)
sibling.parent = parent
end
idx = parent.nodes.index(node)
parent.nodes.insert(idx, sibling) if idx
end
|
.ancestors(node) ⇒ Object
198
199
200
201
202
|
# File 'lib/moxml/adapter/ox.rb', line 198
def ancestors(node)
return [] unless (parent = parent(node))
[parent] + ancestors(parent)
end
|
.assign_parents(node, parent = nil) ⇒ Object
515
516
517
518
519
520
521
522
|
# File 'lib/moxml/adapter/ox.rb', line 515
def assign_parents(node, parent = nil)
node.parent = parent if node.is_a?(::Ox::Element) && parent
return unless node.is_a?(::Ox::Element) || node.is_a?(::Ox::Document)
node.nodes&.each do |child|
assign_parents(child, node)
end
end
|
.at_xpath(node, expression, namespaces = {}) ⇒ Object
672
673
674
675
|
# File 'lib/moxml/adapter/ox.rb', line 672
def at_xpath(node, expression, namespaces = {})
result = xpath(node, expression, namespaces)
result.is_a?(Array) ? result.first : result
end
|
.attribute_element(attribute) ⇒ Object
336
337
338
|
# File 'lib/moxml/adapter/ox.rb', line 336
def attribute_element(attribute)
attribute.parent
end
|
.attributes(element) ⇒ Object
323
324
325
326
327
328
329
330
331
332
333
334
|
# File 'lib/moxml/adapter/ox.rb', line 323
def attributes(element)
return [] unless element.is_a?(::Ox::Element) && element.attributes
element.attributes.filter_map do |name, value|
next if name.to_s.start_with?("xmlns")
::Moxml::Adapter::CustomizedOx::Attribute.new(
name.to_s, value, element
)
end
end
|
.cdata_content(node) ⇒ Object
566
567
568
|
# File 'lib/moxml/adapter/ox.rb', line 566
def cdata_content(node)
node.value.to_s
end
|
.children(node) ⇒ Object
281
282
283
284
285
286
287
288
289
290
291
|
# File 'lib/moxml/adapter/ox.rb', line 281
def children(node)
return [] unless node.is_a?(::Ox::Element) || node.is_a?(::Ox::Document)
result = node.nodes || []
result.each do |child|
child.parent = node if child.is_a?(::Ox::Element)
end
result
end
|
574
575
576
|
# File 'lib/moxml/adapter/ox.rb', line 574
def (node)
node.value.to_s
end
|
.context_adapter_name ⇒ Object
Adapter name used when wrapping bare native nodes; kept
overridable so HeadedOx wraps into its own adapter.
697
698
699
|
# File 'lib/moxml/adapter/ox.rb', line 697
def context_adapter_name
:ox
end
|
.create_document(native_doc = nil) ⇒ Object
80
81
82
83
|
# File 'lib/moxml/adapter/ox.rb', line 80
def create_document(native_doc = nil)
attrs = native_doc&.attributes || {}
::Ox::Document.new(**attrs)
end
|
.create_native_cdata(content, _owner_doc = nil) ⇒ Object
101
102
103
|
# File 'lib/moxml/adapter/ox.rb', line 101
def create_native_cdata(content, _owner_doc = nil)
::Ox::CData.new(content)
end
|
105
106
107
|
# File 'lib/moxml/adapter/ox.rb', line 105
def (content, _owner_doc = nil)
::Ox::Comment.new(content)
end
|
.create_native_declaration(version, encoding, standalone) ⇒ Object
126
127
128
129
130
131
132
|
# File 'lib/moxml/adapter/ox.rb', line 126
def create_native_declaration(version, encoding, standalone)
inst = ::Ox::Instruct.new("xml")
set_attribute(inst, "version", version)
set_attribute(inst, "encoding", encoding)
set_attribute(inst, "standalone", standalone)
inst
end
|
.create_native_doctype(name, external_id, system_id) ⇒ Object
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/moxml/adapter/ox.rb', line 109
def create_native_doctype(name, external_id, system_id)
value = if external_id
"#{name} PUBLIC \"#{external_id}\" \"#{system_id}\""
elsif system_id
"#{name} SYSTEM \"#{system_id}\""
else
name.to_s
end
::Ox::DocType.new(value)
end
|
.create_native_element(name, _owner_doc = nil) ⇒ Object
85
86
87
|
# File 'lib/moxml/adapter/ox.rb', line 85
def create_native_element(name, _owner_doc = nil)
::Ox::Element.new(name)
end
|
.create_native_entity_reference(name) ⇒ Object
.create_native_namespace(element, prefix, uri) ⇒ Object
142
143
144
145
146
147
|
# File 'lib/moxml/adapter/ox.rb', line 142
def create_native_namespace(element, prefix, uri)
ns = ::Moxml::Adapter::CustomizedOx::Namespace.new(prefix, uri,
element)
set_attribute(element, ns.expanded_prefix, uri)
ns
end
|
.create_native_processing_instruction(target, content) ⇒ Object
120
121
122
123
124
|
# File 'lib/moxml/adapter/ox.rb', line 120
def create_native_processing_instruction(target, content)
inst = ::Ox::Instruct.new(target)
set_processing_instruction_content(inst, content)
inst
end
|
.create_native_text(content, _owner_doc = nil) ⇒ Object
89
90
91
|
# File 'lib/moxml/adapter/ox.rb', line 89
def create_native_text(content, _owner_doc = nil)
content
end
|
.declaration_attribute(declaration, attr_name) ⇒ Object
134
135
136
|
# File 'lib/moxml/adapter/ox.rb', line 134
def declaration_attribute(declaration, attr_name)
get_attribute_value(declaration, attr_name)
end
|
.dedupe_natives(natives) ⇒ Object
Identity-based dedup: uniq's value equality would collapse
equal String text nodes.
683
684
685
686
687
688
689
690
691
692
693
|
# File 'lib/moxml/adapter/ox.rb', line 683
def dedupe_natives(natives)
seen = {}
natives.select do |native|
id = native.object_id
if seen[id]
false
else
seen[id] = true
end
end
end
|
.doctype_external_id(native) ⇒ Object
622
623
624
625
626
627
|
# File 'lib/moxml/adapter/ox.rb', line 622
def doctype_external_id(native)
value = native.value.to_s
match = value.match(/PUBLIC\s+"([^"]*)"/)
match ? match[1] : nil
end
|
.doctype_name(native) ⇒ Object
Doctype accessor methods
Ox stores DOCTYPE as a string, so we parse it
615
616
617
618
619
620
|
# File 'lib/moxml/adapter/ox.rb', line 615
def doctype_name(native)
value = native.value.to_s.strip
value.split(/\s+/).first
end
|
.doctype_system_id(native) ⇒ Object
629
630
631
632
633
634
635
636
|
# File 'lib/moxml/adapter/ox.rb', line 629
def doctype_system_id(native)
value = native.value.to_s
matches = value.scan(/"([^"]*)"/)
matches.last&.first
end
|
.document(node) ⇒ Object
313
314
315
316
317
|
# File 'lib/moxml/adapter/ox.rb', line 313
def document(node)
current = node
current = parent(current) while parent(current)
current
end
|
.duplicate_node(node) ⇒ Object
242
243
244
|
# File 'lib/moxml/adapter/ox.rb', line 242
def duplicate_node(node)
Marshal.load(Marshal.dump(node))
end
|
.entity_reference_name(node) ⇒ Object
.get_attribute(element, name) ⇒ Object
381
382
383
384
385
386
387
388
389
390
391
392
393
|
# File 'lib/moxml/adapter/ox.rb', line 381
def get_attribute(element, name)
return unless element.is_a?(::Ox::HasAttrs) && element.attributes
unless element.attributes.key?(name.to_s) || element.attributes.key?(name.to_s.to_sym)
return
end
value = element.attributes[name.to_s] || element.attributes[name.to_s.to_sym]
::Moxml::Adapter::CustomizedOx::Attribute.new(
name.to_s, value, element
)
end
|
.get_attribute_value(element, name) ⇒ Object
395
396
397
|
# File 'lib/moxml/adapter/ox.rb', line 395
def get_attribute_value(element, name)
element[name]
end
|
.has_declaration?(native_doc, _wrapper) ⇒ Boolean
768
769
770
|
# File 'lib/moxml/adapter/ox.rb', line 768
def has_declaration?(native_doc, _wrapper)
native_doc[:version] || native_doc[:encoding] || native_doc[:standalone]
end
|
.inner_text(node) ⇒ Object
551
552
553
554
555
|
# File 'lib/moxml/adapter/ox.rb', line 551
def inner_text(node)
return "" unless node.is_a?(::Ox::Element) || node.is_a?(::Ox::Document)
node.nodes.grep(String).join
end
|
.namespace(element) ⇒ Object
.namespace_definitions(node) ⇒ Object
598
599
600
601
602
603
604
605
606
607
608
609
610
611
|
# File 'lib/moxml/adapter/ox.rb', line 598
def namespace_definitions(node)
return [] unless node.is_a?(::Ox::Element) && node.attributes
namespaces = {}
node.attributes.each do |name, value|
name_s = name.to_s
next unless name_s == "xmlns" || name_s.start_with?("xmlns:")
namespaces[name] = ::Moxml::Adapter::CustomizedOx::Namespace.new(
name, value, node
)
end
namespaces.values
end
|
.namespace_prefix(namespace) ⇒ Object
590
591
592
|
# File 'lib/moxml/adapter/ox.rb', line 590
def namespace_prefix(namespace)
namespace.prefix
end
|
.namespace_uri(namespace) ⇒ Object
594
595
596
|
# File 'lib/moxml/adapter/ox.rb', line 594
def namespace_uri(namespace)
namespace.uri
end
|
.needs_custom_serialize?(node) ⇒ Boolean
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
|
# File 'lib/moxml/adapter/ox.rb', line 717
def needs_custom_serialize?(node)
return true if node.is_a?(::Ox::CData) && node.value&.include?("]]>")
return false unless node.is_a?(::Ox::Document) || node.is_a?(::Ox::Element)
scan_root = node
if node.is_a?(::Ox::Element) && (doc = document(node))
return true if attachments.get(doc, :has_entity_refs)
return true if attachments.get(doc, :has_cdata_end_markers)
return false if attachments.key?(doc, :has_entity_refs) &&
attachments.key?(doc, :has_cdata_end_markers)
scan_root = doc
end
has_er, has_cdata = tree_scan_custom_needs(scan_root)
if scan_root.is_a?(::Ox::Document)
attachments.set(scan_root, :has_entity_refs, has_er)
attachments.set(scan_root, :has_cdata_end_markers, has_cdata)
end
has_er || has_cdata
end
|
.next_sibling(node) ⇒ Object
297
298
299
300
301
302
303
|
# File 'lib/moxml/adapter/ox.rb', line 297
def next_sibling(node)
return unless (parent = node.parent)
siblings = parent.nodes
idx = siblings.index(unpatch_node(node))
idx ? patch_node(siblings[idx + 1], parent) : nil
end
|
.node_name(node) ⇒ Object
224
225
226
227
228
229
230
231
232
233
|
# File 'lib/moxml/adapter/ox.rb', line 224
def node_name(node)
name = begin
node.value
rescue StandardError
node.name
end
name.to_s.split(":", 2).last
end
|
.node_type(node) ⇒ Object
.parent(node) ⇒ Object
293
294
295
|
# File 'lib/moxml/adapter/ox.rb', line 293
def parent(node)
node.parent if node.is_a?(::Ox::Node)
end
|
.parse(xml, options = {}, _context = nil) ⇒ Object
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
|
# File 'lib/moxml/adapter/ox.rb', line 31
def parse(xml, options = {}, _context = nil)
processed_xml = preprocess_entities(xml)
native_doc = begin
result = ::Ox.parse(processed_xml)
if result.is_a?(::Ox::Document)
assign_parents(result)
validate_single_root(result) if options[:strict]
result
else
doc = ::Ox::Document.new
doc << result
assign_parents(doc)
doc
end
rescue ::Ox::ParseError => e
raise Moxml::ParseError.new(
e.message,
source: xml.is_a?(String) ? xml[0..100] : nil,
)
end
ctx = _context || Context.new(context_adapter_name)
Document.new(native_doc, ctx)
end
|
.patch_node(node, parent = nil) ⇒ Object
.patches_children? ⇒ Boolean
246
247
248
|
# File 'lib/moxml/adapter/ox.rb', line 246
def patches_children?
true
end
|
.previous_sibling(node) ⇒ Object
305
306
307
308
309
310
311
|
# File 'lib/moxml/adapter/ox.rb', line 305
def previous_sibling(node)
return unless (parent = parent(node))
siblings = parent.nodes
idx = siblings.index(unpatch_node(node))
idx&.positive? ? patch_node(siblings[idx - 1], parent) : nil
end
|
.processing_instruction_content(node) ⇒ Object
582
583
584
|
# File 'lib/moxml/adapter/ox.rb', line 582
def processing_instruction_content(node)
node.content.to_s
end
|
.processing_instruction_target(node) ⇒ Object
204
205
206
|
# File 'lib/moxml/adapter/ox.rb', line 204
def processing_instruction_target(node)
node.target
end
|
.remove(node) ⇒ Object
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
|
# File 'lib/moxml/adapter/ox.rb', line 474
def remove(node)
return node.clear if node.is_a?(String)
return unless parent(node)
if parent(node).is_a?(::Ox::Document) && node.is_a?(::Ox::Instruct) && node.target == "xml"
doc = parent(node)
doc.attributes&.delete(:version)
doc.attributes&.delete(:encoding)
doc.attributes&.delete(:standalone)
end
parent(node).nodes.delete(unpatch_node(node))
end
|
.remove_attribute(element, name) ⇒ Object
399
400
401
402
403
404
|
# File 'lib/moxml/adapter/ox.rb', line 399
def remove_attribute(element, name)
return unless element.is_a?(::Ox::HasAttrs) && element.attributes
element.attributes.delete(name.to_s)
element.attributes.delete(name.to_s.to_sym)
end
|
.remove_attribute_native(attribute) ⇒ Object
406
407
408
409
410
411
412
|
# File 'lib/moxml/adapter/ox.rb', line 406
def remove_attribute_native(attribute)
expanded = attribute.expanded_name
element = attribute.parent
element.attributes.delete(expanded)
element.attributes.delete(expanded.to_sym)
attribute
end
|
.remove_declaration(native_doc) ⇒ Object
772
773
774
775
776
777
|
# File 'lib/moxml/adapter/ox.rb', line 772
def remove_declaration(native_doc)
native_doc.attributes&.delete(:version)
native_doc.attributes&.delete(:encoding)
native_doc.attributes&.delete(:standalone)
attachments.delete(native_doc, :decl_explicit)
end
|
.replace(node, new_node) ⇒ Object
491
492
493
494
495
496
497
498
499
500
501
502
503
504
|
# File 'lib/moxml/adapter/ox.rb', line 491
def replace(node, new_node)
if node.is_a?(String) && new_node.is_a?(String)
return node.replace(new_node)
end
return unless (parent = parent(node))
new_node.parent = parent if new_node.is_a?(::Ox::Node)
idx = parent.nodes.index(node)
parent.nodes[idx] = new_node if idx
end
|
.replace_children(node, new_children) ⇒ Object
506
507
508
509
510
511
512
513
|
# File 'lib/moxml/adapter/ox.rb', line 506
def replace_children(node, new_children)
node.remove_children_by_path("*")
new_children.each do |child|
child.parent = node if child.is_a?(::Ox::Node)
node << child
end
node
end
|
.root(document) ⇒ Object
319
320
321
|
# File 'lib/moxml/adapter/ox.rb', line 319
def root(document)
document.nodes&.find { |node| node.is_a?(::Ox::Element) }
end
|
.sax_parse(xml, handler) ⇒ void
This method returns an undefined value.
SAX parsing implementation for Ox
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/moxml/adapter/ox.rb', line 63
def sax_parse(xml, handler)
bridge = OxSAXBridge.new(handler)
xml_string = xml.is_a?(IO) || xml.is_a?(StringIO) ? xml.read : xml.to_s
begin
::Ox.sax_parse(bridge, StringIO.new(xml_string))
bridge.end_document
rescue ::Ox::ParseError => e
error = Moxml::ParseError.new(e.message)
handler.on_error(error)
end
end
|
.serialize(node, options = {}) ⇒ Object
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
|
# File 'lib/moxml/adapter/ox.rb', line 701
def serialize(node, options = {})
return XmlEmitter.escape_text(node.value) if node.is_a?(CustomizedOx::Text)
needs_custom = needs_custom_serialize?(node)
unless needs_custom
return serialize_standard(node, options)
end
serialize_custom(node, options)
end
|
.set_attribute(element, name, value) ⇒ Object
340
341
342
343
344
345
346
347
348
349
350
351
352
|
# File 'lib/moxml/adapter/ox.rb', line 340
def set_attribute(element, name, value)
element.attributes ||= {}
if value.nil?
remove_attribute(element, name)
else
element.attributes[name.to_s] = value
end
::Moxml::Adapter::CustomizedOx::Attribute.new(
name.to_s, value&.to_s, element
)
end
|
.set_attribute_name(attribute, name) ⇒ Object
354
355
356
357
358
359
360
361
362
|
# File 'lib/moxml/adapter/ox.rb', line 354
def set_attribute_name(attribute, name)
old_name = attribute.name
attribute.name = name.to_s
element = attribute.parent
element.attributes.delete(old_name)
element.attributes[name] = attribute.value
attribute
end
|
.set_attribute_value(attribute, new_value) ⇒ Object
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
|
# File 'lib/moxml/adapter/ox.rb', line 364
def set_attribute_value(attribute, new_value)
if new_value.nil?
remove_attribute(attribute.parent, attribute.name)
else
element = attribute.parent
expanded = attribute.expanded_name
element.attributes.delete(expanded.to_sym)
element.attributes[expanded] = new_value
attribute.value = new_value
end
attribute
end
|
.set_cdata_content(node, content) ⇒ Object
570
571
572
|
# File 'lib/moxml/adapter/ox.rb', line 570
def set_cdata_content(node, content)
node.value = content.to_s
end
|
578
579
580
|
# File 'lib/moxml/adapter/ox.rb', line 578
def (node, content)
node.value = content.to_s
end
|
.set_declaration_attribute(declaration, attr_name, value) ⇒ Object
138
139
140
|
# File 'lib/moxml/adapter/ox.rb', line 138
def set_declaration_attribute(declaration, attr_name, value)
set_attribute(declaration, attr_name, value)
end
|
.set_namespace(element, ns) ⇒ Object
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/moxml/adapter/ox.rb', line 149
def set_namespace(element, ns)
return element unless element.is_a?(::Ox::Element) || element.is_a?(::Ox::Node)
prefix = ns.prefix
if element.is_a?(::Ox::Element)
set_attribute(element, ns.expanded_prefix,
ns.uri)
end
element.name = [prefix,
element.name.delete_prefix("xmlns:")].compact.join(":")
element
end
|
.set_node_name(node, name) ⇒ Object
235
236
237
238
239
240
|
# File 'lib/moxml/adapter/ox.rb', line 235
def set_node_name(node, name)
case node
when ::Ox::Element then node.name = name
when ::Ox::Instruct then node.value = name
end
end
|
.set_processing_instruction_content(node, content) ⇒ Object
586
587
588
|
# File 'lib/moxml/adapter/ox.rb', line 586
def set_processing_instruction_content(node, content)
node.content = content.to_s
end
|
.set_root(doc, element) ⇒ Object
18
19
20
21
22
23
24
25
26
27
28
29
|
# File 'lib/moxml/adapter/ox.rb', line 18
def set_root(doc, element)
existing_root = root(doc)
element.parent = doc if element.is_a?(::Ox::Node)
if existing_root
idx = doc.nodes.index(existing_root)
doc.nodes[idx] = element
else
doc << element
end
end
|
.set_text_content(node, content) ⇒ Object
557
558
559
560
561
562
563
564
|
# File 'lib/moxml/adapter/ox.rb', line 557
def set_text_content(node, content)
case node
when String then node.replace(content.to_s)
when ::Ox::Element then node.replace_text(content.to_s)
else
node.value = content.to_s
end
end
|
.text_content(node) ⇒ Object
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
|
# File 'lib/moxml/adapter/ox.rb', line 534
def text_content(node)
return "" if node.nil?
case node
when String then node.to_s
when ::Moxml::Adapter::CustomizedOx::Text then node.value
when ::Ox::CData then node.value.to_s
when ::Moxml::Adapter::CustomizedOx::EntityReference then ""
else
return "" unless node.is_a?(::Ox::Element) || node.is_a?(::Ox::Document)
node.nodes.map do |n|
text_content(n)
end.join
end
end
|
.tree_scan_custom_needs(node) ⇒ Object
Single walk collecting both custom-serialize triggers.
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
|
# File 'lib/moxml/adapter/ox.rb', line 749
def tree_scan_custom_needs(node)
has_er = false
has_cdata = false
stack = [node]
until stack.empty?
current = stack.pop
case current
when ::Moxml::Adapter::CustomizedOx::EntityReference
has_er = true
when ::Ox::CData
has_cdata = true if current.value&.include?("]]>")
when ::Ox::Element, ::Ox::Document
current.nodes&.each { |child| stack << child }
end
return [true, has_cdata] if has_er
end
[has_er, has_cdata]
end
|
.unpatch_node(node) ⇒ Object
.validate_single_root(document) ⇒ Object
524
525
526
527
528
529
530
531
532
|
# File 'lib/moxml/adapter/ox.rb', line 524
def validate_single_root(document)
elements = document.nodes&.grep(::Ox::Element) || []
return unless elements.size > 1
raise Moxml::ParseError.new(
"Multiple root elements found",
source: nil,
)
end
|
.xpath(node, expression, namespaces = {}) ⇒ Object
XPath runs through Moxml's pure-Ruby XPath 1.0 engine (shared
with HeadedOx and Leptris). Ox's locate() only covers a
small XPath subset; the engine provides all axes,
predicates, functions and variables.
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
# File 'lib/moxml/adapter/ox.rb', line 642
def xpath(node, expression, namespaces = {})
wrapped = if node.is_a?(Moxml::Node)
node
else
Moxml::Node.wrap(node, Context.new(context_adapter_name))
end
ast = XPath::Parser.parse(expression)
proc = XPath::Compiler.compile_with_cache(ast, namespaces: namespaces)
result = proc.call(wrapped)
case result
when Array
dedupe_natives(result.map do |n|
n.is_a?(Moxml::Node) ? n.native : n
end)
when NodeSet
dedupe_natives(result.to_a.map(&:native))
else
result
end
rescue StandardError => e
raise Moxml::XPathError.new(
"XPath execution failed: #{e.message}",
expression: expression,
adapter: "Ox",
node: node,
)
end
|
.xpath_supported? ⇒ Boolean
677
678
679
|
# File 'lib/moxml/adapter/ox.rb', line 677
def xpath_supported?
true
end
|