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
135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/canon/diff/node_serializer.rb', line 135 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
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 122 123 124 125 126 127 128 |
# File 'lib/canon/diff/node_serializer.rb', line 96 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
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 59 60 61 62 63 64 65 |
# File 'lib/canon/diff/node_serializer.rb', line 24 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
177 178 179 180 181 182 183 |
# File 'lib/canon/diff/node_serializer.rb', line 177 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
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/canon/diff/node_serializer.rb', line 71 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
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/canon/diff/node_serializer.rb', line 155 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 |