class Canon::Comparison::XmlComparatorHelpers::NodeParser
Handles conversion of strings and various node types to Canon::Xml::Node
Node parser with preprocessing support
def self.apply_preprocessing(xml_string, preprocessing)
-
(String)- Preprocessed XML string
Parameters:
-
preprocessing(Symbol) -- Preprocessing mode -
xml_string(String) -- XML string to preprocess
def self.apply_preprocessing(xml_string, preprocessing) case preprocessing when :normalize # Normalize whitespace: collapse runs, trim lines xml_string.lines.map(&:strip).reject(&:empty?).join("\n") when :c14n # Canonicalize the XML Canon::Xml::C14n.canonicalize(xml_string, with_comments: false) when :format # Pretty format the XML Canon.format(xml_string, :xml) else # :none or unrecognized - use as-is xml_string end end
def self.convert_from_node(node, preserve_whitespace: false,
-
(Canon::Xml::Node)- Converted node
Parameters:
-
parser(Symbol, nil) -- Parser backend override -
preserve_whitespace(Boolean) -- Whether to preserve whitespace-only text nodes -
node(Object) -- Nokogiri or Moxml node
def self.convert_from_node(node, preserve_whitespace: false, nil) if Canon::XmlBackend.nokogiri? if node.is_a?(Nokogiri::XML::Node) return Canon::Xml::DataModel.build_from_nokogiri( node, preserve_whitespace: preserve_whitespace ) end elsif node.is_a?(Moxml::Node) return Canon::Xml::DataModel.build_from_moxml( node, preserve_whitespace: preserve_whitespace ) end xml_str = if node.is_a?(String) node else node.to_xml end resolved_parser = parser || resolve_parser_config if resolved_parser == :sax && RUBY_ENGINE != "opal" Canon::Xml::SaxBuilder.parse(xml_str, preserve_whitespace: preserve_whitespace) else Canon::Xml::DataModel.from_xml(xml_str, preserve_whitespace: preserve_whitespace) end end
def self.parse(node, preprocessing = :none, preserve_whitespace: false,
-
(Canon::Xml::Node)- Parsed node
Parameters:
-
parser(Symbol) -- Parser backend (:sax or :dom, default from config) -
preserve_whitespace(Boolean) -- Whether to preserve whitespace-only text nodes -
preprocessing(Symbol) -- Preprocessing mode (:none, :normalize, :c14n, :format) -
node(String, Object) -- Node to parse
def self.parse(node, preprocessing = :none, preserve_whitespace: false, parser: nil) # If already a Canon::Xml::Node, return as-is return node if node.is_a?(Canon::Xml::Node) # If it's a Nokogiri or Moxml node, convert to DataModel unless node.is_a?(String) return convert_from_node(node, preserve_whitespace: preserve_whitespace, parser: parser) end # Normalize encoding before preprocessing (UTF-16 strings can't use strip, etc.) node = Canon::Xml::DataModel.normalize_encoding(node) # Apply preprocessing to XML string before parsing xml_string = apply_preprocessing(node, preprocessing).strip # Select parser backend resolved_parser = parser || resolve_parser_config if resolved_parser == :sax && RUBY_ENGINE != "opal" Canon::Xml::SaxBuilder.parse(xml_string, preserve_whitespace: preserve_whitespace) else Canon::Xml::DataModel.from_xml(xml_string, preserve_whitespace: preserve_whitespace) end end
def self.resolve_parser_config
-
(Symbol)- :sax or :dom
def self.resolve_parser_config Canon::Config.instance.xml.diff.parser rescue StandardError Canon::XmlBackend.nokogiri? ? :sax : :dom end