Class: Canon::Diff::NodeSerializer
- Inherits:
-
Object
- Object
- Canon::Diff::NodeSerializer
- Defined in:
- lib/canon/diff/node_serializer.rb
Overview
Serializes nodes from different parsing libraries into canonical strings This abstraction allows Canon to work with any parsing library (Nokogiri, Moxml, etc.) without being tied to a specific implementation.
This is library-agnostic because it detects node type and uses the appropriate serialization method.
Class Method Summary collapse
-
.element_name(node) ⇒ String
Get element name from a node Handles both Nokogiri and Canon nodes.
-
.extract_attributes(node) ⇒ Hash
Extract attributes from a node as a normalized hash Handles both Nokogiri and Canon nodes.
-
.serialize(node) ⇒ String
Serialize a node to a string for display Handles both Nokogiri and Canon nodes.
-
.serialize_attributes(attributes) ⇒ String
Serialize attributes to string format Returns attributes in “ name="value"” format.
-
.serialize_element_node(element) ⇒ String
Serialize an ElementNode to HTML/XML string.
-
.text_content(node) ⇒ String
Get text content from a node Handles both Nokogiri and Canon nodes.
Class Method Details
.element_name(node) ⇒ String
Get element name from a node Handles both Nokogiri and Canon nodes
128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/canon/diff/node_serializer.rb', line 128 def self.element_name(node) return "" if node.nil? # Handle Canon::Xml::Nodes::ElementNode if node.is_a?(Canon::Xml::Nodes::ElementNode) return node.name end # Handle Nokogiri/moxml elements name = Canon::XmlParsing.name(node) return name.to_s if name "" end |
.extract_attributes(node) ⇒ Hash
Extract attributes from a node as a normalized hash Handles both Nokogiri and Canon nodes
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/canon/diff/node_serializer.rb', line 89 def self.extract_attributes(node) return {} if node.nil? # Handle Canon::Xml::Nodes::ElementNode if node.is_a?(Canon::Xml::Nodes::ElementNode) attrs = {} node.attribute_nodes.each do |attr| attrs[attr.name] = attr.value end return attrs end # Handle Nokogiri/moxml elements via XmlParsing if Canon::XmlParsing.element?(node) attrs = {} Canon::XmlParsing.attributes(node).each do |attr| attrs[attr.name] = attr.value end return attrs end # Handle other elements with attributes method if node.is_a?(Canon::Xml::Node) return {} end # Handle TreeNode attributes (already a hash) if node.is_a?(Hash) return node end {} end |
.serialize(node) ⇒ String
Serialize a node to a string for display Handles both Nokogiri and Canon nodes
17 18 19 20 21 22 23 24 25 26 27 28 29 30 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 57 58 |
# File 'lib/canon/diff/node_serializer.rb', line 17 def self.serialize(node) return "" if node.nil? # Handle Canon::Xml::Nodes::TextNode if node.is_a?(Canon::Xml::Nodes::TextNode) # Use original text (with entity references) if available, # otherwise fall back to value (decoded text) return node.original || node.value end # Handle Canon::Xml::Nodes::CommentNode if node.is_a?(Canon::Xml::Nodes::CommentNode) return "<!--#{node.value}-->" end # Handle Canon::Xml::Nodes::ElementNode if node.is_a?(Canon::Xml::Nodes::ElementNode) return serialize_element_node(node) end # Handle Canon::Xml::Nodes::ProcessingInstructionNode if node.is_a?(Canon::Xml::Nodes::ProcessingInstructionNode) return "<?#{node.target} #{node.data}?>" end # Handle Canon::Xml::Nodes::RootNode - serialize children if node.is_a?(Canon::Xml::Nodes::RootNode) return node.children.map { |child| serialize(child) }.join end # Handle Nokogiri/moxml nodes if Canon::XmlParsing.xml_node?(node) return Canon::XmlParsing.serialize(node) end # Handle tree diff nodes and other objects with serialization if node.is_a?(Canon::TreeDiff::Core::TreeNode) return serialize_treenode(node) end node.to_s end |
.serialize_attributes(attributes) ⇒ String
Serialize attributes to string format Returns attributes in “ name="value"” format
170 171 172 173 174 175 176 |
# File 'lib/canon/diff/node_serializer.rb', line 170 def self.serialize_attributes(attributes) return "" if attributes.nil? || attributes.empty? attributes.sort.map do |name, value| " #{name}=\"#{value}\"" end.join end |
.serialize_element_node(element) ⇒ String
Serialize an ElementNode to HTML/XML string
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/canon/diff/node_serializer.rb', line 64 def self.serialize_element_node(element) # Build opening tag with attributes tag = "<#{element.name}" # Add attributes element.sorted_attribute_nodes.each do |attr| tag += " #{attr.name}=\"#{attr.value}\"" end # Check if element has children if element.children.empty? # Self-closing tag for empty elements "#{tag}/>" else # Full element with children content = element.children.map { |child| serialize(child) }.join "#{tag}>#{content}</#{element.name}>" end end |
.text_content(node) ⇒ String
Get text content from a node Handles both Nokogiri and Canon nodes
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/canon/diff/node_serializer.rb', line 148 def self.text_content(node) return "" if node.nil? # Handle Canon::Xml::Nodes::TextNode if node.is_a?(Canon::Xml::Nodes::TextNode) return node.value.to_s end # Handle Canon::Xml::Node if node.is_a?(Canon::Xml::Node) return node.text_content.to_s end # Handle Nokogiri/moxml nodes Canon::XmlParsing.text_content(node).to_s end |