Module: Canon::XmlParsing
- Defined in:
- lib/canon/xml_parsing.rb
Overview
Backend-agnostic XML parsing, serialization, and type dispatch.
Provides a unified API that delegates to the active backend (Nokogiri or moxml/Oga). Uses backend-branching (‘if XmlBackend.nokogiri?`) rather than `case/when` with constant references — this ensures Nokogiri constants are never resolved under Opal, preventing NameError at runtime.
OCP: adding a new backend only requires updating this module. DRY: all backend dispatch centralized here, not scattered across comparator/formatter files.
Class Method Summary collapse
- .attribute_value(node, attr_name) ⇒ Object
- .attributes(node) ⇒ Object
- .canonicalize(node, options = {}) ⇒ Object
- .cdata?(node) ⇒ Boolean
-
.children(node) ⇒ Object
— Node traversal —.
- .comment?(node) ⇒ Boolean
-
.document?(obj) ⇒ Boolean
— Type checks (backend-safe) —.
- .document_fragment?(obj) ⇒ Boolean
- .dtd?(node) ⇒ Boolean
- .element?(node) ⇒ Boolean
- .moxml_context ⇒ Object
- .name(node) ⇒ Object
- .namespace_definitions(node) ⇒ Object
- .namespace_uri(node) ⇒ Object
-
.node_type(node) ⇒ Object
Returns a symbol for all backends (:element, :text, :comment, etc.) or nil for unrecognised nodes.
- .parent(node) ⇒ Object
-
.parse(xml_string, options = {}) ⇒ Object
— Parsing —.
- .parse_fragment(xml_string) ⇒ Object
- .processing_instruction?(node) ⇒ Boolean
-
.serialize(node) ⇒ Object
— Serialization —.
- .text_content(node) ⇒ Object
- .text_node?(node) ⇒ Boolean
- .xml_node?(obj) ⇒ Boolean
Class Method Details
.attribute_value(node, attr_name) ⇒ Object
157 158 159 160 161 162 163 |
# File 'lib/canon/xml_parsing.rb', line 157 def attribute_value(node, attr_name) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Element) ? node[attr_name.to_s] : nil else node.is_a?(Moxml::Element) ? node[attr_name.to_s] : nil end end |
.attributes(node) ⇒ Object
149 150 151 152 153 154 155 |
# File 'lib/canon/xml_parsing.rb', line 149 def attributes(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Element) ? node.attributes.values : [] else node.is_a?(Moxml::Element) ? node.attributes : [] end end |
.canonicalize(node, options = {}) ⇒ Object
199 200 201 202 203 204 205 |
# File 'lib/canon/xml_parsing.rb', line 199 def canonicalize(node, = {}) if XmlBackend.nokogiri? node.canonicalize() else moxml_canonicalize(node, ) end end |
.cdata?(node) ⇒ Boolean
91 92 93 94 95 96 97 |
# File 'lib/canon/xml_parsing.rb', line 91 def cdata?(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::CDATA) else node.is_a?(Moxml::Cdata) end end |
.children(node) ⇒ Object
— Node traversal —
125 126 127 128 129 130 131 |
# File 'lib/canon/xml_parsing.rb', line 125 def children(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Node) ? node.children.to_a : [] else node.is_a?(Moxml::Node) ? node.children.to_a : [] end end |
.comment?(node) ⇒ Boolean
83 84 85 86 87 88 89 |
# File 'lib/canon/xml_parsing.rb', line 83 def comment?(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Comment) else node.is_a?(Moxml::Comment) end end |
.document?(obj) ⇒ Boolean
— Type checks (backend-safe) —
51 52 53 54 55 56 57 |
# File 'lib/canon/xml_parsing.rb', line 51 def document?(obj) if XmlBackend.nokogiri? obj.is_a?(Nokogiri::XML::Document) else obj.is_a?(Moxml::Document) end end |
.document_fragment?(obj) ⇒ Boolean
107 108 109 110 111 112 113 |
# File 'lib/canon/xml_parsing.rb', line 107 def document_fragment?(obj) if XmlBackend.nokogiri? obj.is_a?(Nokogiri::XML::DocumentFragment) else obj.is_a?(Moxml::DocumentFragment) end end |
.dtd?(node) ⇒ Boolean
115 116 117 118 119 120 121 |
# File 'lib/canon/xml_parsing.rb', line 115 def dtd?(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::DTD) else false end end |
.element?(node) ⇒ Boolean
67 68 69 70 71 72 73 |
# File 'lib/canon/xml_parsing.rb', line 67 def element?(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Element) else node.is_a?(Moxml::Element) end end |
.moxml_context ⇒ Object
16 17 18 |
# File 'lib/canon/xml_parsing.rb', line 16 def moxml_context @moxml_context ||= Moxml.new(:oga) end |
.name(node) ⇒ Object
133 134 135 136 137 138 139 |
# File 'lib/canon/xml_parsing.rb', line 133 def name(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Node) ? node.name : nil else node.is_a?(Moxml::Node) ? node.name : nil end end |
.namespace_definitions(node) ⇒ Object
165 166 167 168 169 170 171 |
# File 'lib/canon/xml_parsing.rb', line 165 def namespace_definitions(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Element) ? node.namespace_definitions : [] else node.is_a?(Moxml::Element) ? node.namespace_definitions : [] end end |
.namespace_uri(node) ⇒ Object
181 182 183 184 185 186 187 |
# File 'lib/canon/xml_parsing.rb', line 181 def namespace_uri(node) if XmlBackend.nokogiri? node.namespace&.href if node.is_a?(Nokogiri::XML::Element) elsif node.is_a?(Moxml::Element) node.namespace_uri end end |
.node_type(node) ⇒ Object
Returns a symbol for all backends (:element, :text, :comment, etc.) or nil for unrecognised nodes.
191 192 193 194 195 196 197 |
# File 'lib/canon/xml_parsing.rb', line 191 def node_type(node) if XmlBackend.nokogiri? nokogiri_node_type(node) else moxml_node_type(node) end end |
.parent(node) ⇒ Object
173 174 175 176 177 178 179 |
# File 'lib/canon/xml_parsing.rb', line 173 def parent(node) return nil unless xml_node?(node) # Document nodes have no parent return nil if document?(node) node.parent end |
.parse(xml_string, options = {}) ⇒ Object
— Parsing —
22 23 24 25 26 27 28 |
# File 'lib/canon/xml_parsing.rb', line 22 def parse(xml_string, = {}) if XmlBackend.nokogiri? nokogiri_parse(xml_string, ) else moxml_parse(xml_string, ) end end |
.parse_fragment(xml_string) ⇒ Object
30 31 32 33 34 35 36 37 |
# File 'lib/canon/xml_parsing.rb', line 30 def parse_fragment(xml_string) if XmlBackend.nokogiri? Nokogiri::XML.fragment(xml_string).children.to_a else doc = moxml_context.parse("<__frag__>#{xml_string}</__frag__>") doc.root.children.to_a end end |
.processing_instruction?(node) ⇒ Boolean
99 100 101 102 103 104 105 |
# File 'lib/canon/xml_parsing.rb', line 99 def processing_instruction?(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::ProcessingInstruction) else node.is_a?(Moxml::ProcessingInstruction) end end |
.serialize(node) ⇒ Object
— Serialization —
41 42 43 44 45 46 47 |
# File 'lib/canon/xml_parsing.rb', line 41 def serialize(node) if XmlBackend.nokogiri? nokogiri_serialize(node) else moxml_serialize(node) end end |
.text_content(node) ⇒ Object
141 142 143 144 145 146 147 |
# File 'lib/canon/xml_parsing.rb', line 141 def text_content(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Node) ? node.content : node.to_s else node.is_a?(Moxml::Node) ? node.text : node.to_s end end |
.text_node?(node) ⇒ Boolean
75 76 77 78 79 80 81 |
# File 'lib/canon/xml_parsing.rb', line 75 def text_node?(node) if XmlBackend.nokogiri? node.is_a?(Nokogiri::XML::Text) else node.is_a?(Moxml::Text) end end |
.xml_node?(obj) ⇒ Boolean
59 60 61 62 63 64 65 |
# File 'lib/canon/xml_parsing.rb', line 59 def xml_node?(obj) if XmlBackend.nokogiri? obj.is_a?(Nokogiri::XML::Node) else obj.is_a?(Moxml::Node) end end |