Class: Moxml::Node
Direct Known Subclasses
Attribute, Cdata, Comment, Declaration, Doctype, Document, Element, EntityReference, Namespace, ProcessingInstruction, Text
Constant Summary collapse
- TYPES =
%i[ element text cdata comment processing_instruction document declaration doctype namespace attribute unknown entity_reference ].freeze
Instance Attribute Summary collapse
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#native ⇒ Object
readonly
Returns the value of attribute native.
-
#parent_node ⇒ Object
writeonly
Internal: Set the parent node for cache invalidation tracking.
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#[](name) ⇒ Object
Attribute accessor - only works on Element nodes Returns nil for non-element nodes.
- #add_child(node) ⇒ Object
- #add_next_sibling(node) ⇒ Object
- #add_previous_sibling(node) ⇒ Object
- #at_xpath(expression, namespaces = {}) ⇒ Object
- #children ⇒ Object
-
#clone ⇒ Object
(also: #dup)
Clone node (deep copy).
- #document ⇒ Object
-
#each_node(&block) ⇒ Object
Recursively yield all descendant nodes Used by XPath descendant-or-self and descendant axes.
-
#find(xpath_expression, namespaces = {}) ⇒ Object
Convenience find methods (aliases for xpath methods).
- #find_all(xpath_expression, namespaces = {}) ⇒ Object
-
#first_child ⇒ Object
Get first/last child.
-
#has_children? ⇒ Boolean
Check if node has any children.
-
#identifier ⇒ String?
Returns the primary identifier for this node type For Element: the tag name For Attribute: the attribute name For ProcessingInstruction: the target For content nodes (Text, Comment, Cdata, Declaration): nil (no identifier) For Doctype: nil (not fully implemented across adapters).
-
#initialize(native, context) ⇒ Node
constructor
A new instance of Node.
- #last_child ⇒ Object
-
#namespace ⇒ Object
Returns the namespace of this node Only applicable to Element nodes, returns nil for others.
-
#namespaces ⇒ Object
Returns all namespace definitions on this node Only applicable to Element nodes, returns empty array for others.
- #next_sibling ⇒ Object
- #parent ⇒ Object
- #previous_sibling ⇒ Object
-
#refresh_native!(new_native) ⇒ Object
Update native reference after identity-changing operations (e.g., LibXML doc.root= creates a new Ruby wrapper).
- #remove ⇒ Object
- #replace(node) ⇒ Object
-
#text ⇒ Object
Returns the text content of this node Subclasses should override this method Element and Text have their own implementations.
- #to_xml(options = {}) ⇒ Object
- #xpath(expression, namespaces = {}) ⇒ Object
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
Constructor Details
#initialize(native, context) ⇒ Node
Returns a new instance of Node.
17 18 19 20 21 |
# File 'lib/moxml/node.rb', line 17 def initialize(native, context) @context = context @native = native @parent_node = nil end |
Instance Attribute Details
#context ⇒ Object (readonly)
Returns the value of attribute context.
15 16 17 |
# File 'lib/moxml/node.rb', line 15 def context @context end |
#native ⇒ Object (readonly)
Returns the value of attribute native.
15 16 17 |
# File 'lib/moxml/node.rb', line 15 def native @native end |
#parent_node=(value) ⇒ Object (writeonly)
Internal: Set the parent node for cache invalidation tracking. Called by NodeSet, Document, Element when establishing parent-child relationships. Public to allow cross-class usage within Moxml internals.
243 244 245 |
# File 'lib/moxml/node.rb', line 243 def parent_node=(value) @parent_node = value end |
Class Method Details
.adapter(context) ⇒ Object
251 252 253 |
# File 'lib/moxml/node.rb', line 251 def self.adapter(context) context.config.adapter end |
.wrap(node, context) ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/moxml/node.rb', line 220 def self.wrap(node, context) return nil if node.nil? klass = case adapter(context).node_type(node) when :element then Element when :text then Text when :cdata then Cdata when :comment then Comment when :processing_instruction then ProcessingInstruction when :document then Document when :declaration then Declaration when :doctype then Doctype when :attribute then Attribute when :entity_reference then EntityReference else self end klass.new(node, context) end |
Instance Method Details
#==(other) ⇒ Object
198 199 200 |
# File 'lib/moxml/node.rb', line 198 def ==(other) self.class == other.class && @native == other.native end |
#[](name) ⇒ Object
Attribute accessor - only works on Element nodes Returns nil for non-element nodes
157 158 159 160 161 162 |
# File 'lib/moxml/node.rb', line 157 def [](name) return nil unless respond_to?(:attribute) attr = attribute(name) attr&.value if attr.respond_to?(:value) end |
#add_child(node) ⇒ Object
53 54 55 56 57 58 59 60 61 62 |
# File 'lib/moxml/node.rb', line 53 def add_child(node) node = prepare_node(node) adapter.add_child(@native, node.native) # Refresh native in case adapter changed identity (e.g., LibXML doc.root=) refreshed = adapter.actual_native(node.native, @native) node.refresh_native!(refreshed) if refreshed && refreshed != node.native node.parent_node = self invalidate_children_cache! self end |
#add_next_sibling(node) ⇒ Object
71 72 73 74 75 76 |
# File 'lib/moxml/node.rb', line 71 def add_next_sibling(node) node = prepare_node(node) adapter.add_next_sibling(@native, node.native) invalidate_parent_children_cache! self end |
#add_previous_sibling(node) ⇒ Object
64 65 66 67 68 69 |
# File 'lib/moxml/node.rb', line 64 def add_previous_sibling(node) node = prepare_node(node) adapter.add_previous_sibling(@native, node.native) invalidate_parent_children_cache! self end |
#at_xpath(expression, namespaces = {}) ⇒ Object
107 108 109 110 |
# File 'lib/moxml/node.rb', line 107 def at_xpath(expression, namespaces = {}) Moxml::Node.wrap(adapter.at_xpath(@native, expression, namespaces), context) end |
#children ⇒ Object
37 38 39 40 41 42 43 |
# File 'lib/moxml/node.rb', line 37 def children @children ||= NodeSet.new( adapter.children(@native).map { adapter.patch_node(_1, @native) }, context, self, ) end |
#clone ⇒ Object Also known as: dup
Clone node (deep copy)
193 194 195 |
# File 'lib/moxml/node.rb', line 193 def clone Moxml::Node.wrap(adapter.dup(@native), context) end |
#document ⇒ Object
29 30 31 |
# File 'lib/moxml/node.rb', line 29 def document Document.wrap(adapter.document(@native), context) end |
#each_node(&block) ⇒ Object
Recursively yield all descendant nodes Used by XPath descendant-or-self and descendant axes
185 186 187 188 189 190 |
# File 'lib/moxml/node.rb', line 185 def each_node(&block) children.each do |child| yield child child.each_node(&block) if child.respond_to?(:each_node) end end |
#find(xpath_expression, namespaces = {}) ⇒ Object
Convenience find methods (aliases for xpath methods)
113 114 115 |
# File 'lib/moxml/node.rb', line 113 def find(xpath_expression, namespaces = {}) at_xpath(xpath_expression, namespaces) end |
#find_all(xpath_expression, namespaces = {}) ⇒ Object
117 118 119 |
# File 'lib/moxml/node.rb', line 117 def find_all(xpath_expression, namespaces = {}) xpath(xpath_expression, namespaces).to_a end |
#first_child ⇒ Object
Get first/last child
127 128 129 |
# File 'lib/moxml/node.rb', line 127 def first_child children.first end |
#has_children? ⇒ Boolean
Check if node has any children
122 123 124 |
# File 'lib/moxml/node.rb', line 122 def has_children? !children.empty? end |
#identifier ⇒ String?
Returns the primary identifier for this node type For Element: the tag name For Attribute: the attribute name For ProcessingInstruction: the target For content nodes (Text, Comment, Cdata, Declaration): nil (no identifier) For Doctype: nil (not fully implemented across adapters)
216 217 218 |
# File 'lib/moxml/node.rb', line 216 def identifier nil end |
#last_child ⇒ Object
131 132 133 |
# File 'lib/moxml/node.rb', line 131 def last_child children.last end |
#namespace ⇒ Object
Returns the namespace of this node Only applicable to Element nodes, returns nil for others
166 167 168 169 170 171 |
# File 'lib/moxml/node.rb', line 166 def namespace return nil unless element? ns = adapter.namespace(@native) ns && Namespace.new(ns, context) end |
#namespaces ⇒ Object
Returns all namespace definitions on this node Only applicable to Element nodes, returns empty array for others
175 176 177 178 179 180 181 |
# File 'lib/moxml/node.rb', line 175 def namespaces return [] unless element? adapter.namespace_definitions(@native).map do |ns| Namespace.new(ns, context) end end |
#next_sibling ⇒ Object
45 46 47 |
# File 'lib/moxml/node.rb', line 45 def next_sibling Moxml::Node.wrap(adapter.next_sibling(@native), context) end |
#parent ⇒ Object
33 34 35 |
# File 'lib/moxml/node.rb', line 33 def parent Moxml::Node.wrap(adapter.parent(@native), context) end |
#previous_sibling ⇒ Object
49 50 51 |
# File 'lib/moxml/node.rb', line 49 def previous_sibling Moxml::Node.wrap(adapter.previous_sibling(@native), context) end |
#refresh_native!(new_native) ⇒ Object
Update native reference after identity-changing operations (e.g., LibXML doc.root= creates a new Ruby wrapper)
25 26 27 |
# File 'lib/moxml/node.rb', line 25 def refresh_native!(new_native) @native = new_native end |
#remove ⇒ Object
78 79 80 81 82 83 |
# File 'lib/moxml/node.rb', line 78 def remove invalidate_parent_children_cache! adapter.remove(@native) invalidate_children_cache! self end |
#replace(node) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/moxml/node.rb', line 85 def replace(node) node = prepare_node(node) invalidate_parent_children_cache! adapter.replace(@native, node.native) invalidate_children_cache! self end |
#text ⇒ Object
Returns the text content of this node Subclasses should override this method Element and Text have their own implementations
138 139 140 141 142 143 144 145 146 |
# File 'lib/moxml/node.rb', line 138 def text if respond_to?(:content) content elsif respond_to?(:children) children.grep(Text).map(&:content).join else "" end end |
#to_xml(options = {}) ⇒ Object
93 94 95 96 97 98 99 100 101 |
# File 'lib/moxml/node.rb', line 93 def to_xml( = {}) # Determine if we should include XML declaration # For Document nodes: check native then wrapper, unless explicitly overridden # For other nodes: default to no declaration unless explicitly set = .merge() [:no_declaration] = !should_include_declaration?() adapter.serialize(@native, ) end |