Module: EquivalentXml
- Defined in:
- lib/equivalent-xml.rb
Defined Under Namespace
Modules: RSpecMatchers
Constant Summary collapse
- DEFAULT_OPTS =
{ :ignore_attr_values => false, :element_order => false, :normalize_whitespace => true }
Class Method Summary collapse
- .compare_attributes(node_1, node_2, opts, &block) ⇒ Object
- .compare_cdata(node_1, node_2, opts, &block) ⇒ Object
- .compare_children(node_1, node_2, opts, &block) ⇒ Object
- .compare_documents(node_1, node_2, opts, &block) ⇒ Object
- .compare_elements(node_1, node_2, opts, &block) ⇒ Object
- .compare_nodes(node_1, node_2, opts, &block) ⇒ Object
- .compare_nodesets(nodeset_1, nodeset_2, opts, &block) ⇒ Object
- .compare_text(node_1, node_2, opts, &block) ⇒ Object
-
.equivalent?(node_1, node_2, opts = {}) {|n1, n2, result| ... } ⇒ Boolean
Determine if two XML documents or nodes are equivalent.
-
.same_namespace?(node_1, node_2) ⇒ Boolean
Determine if two nodes are in the same effective Namespace.
Class Method Details
.compare_attributes(node_1, node_2, opts, &block) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/equivalent-xml.rb', line 70 def compare_attributes(node_1, node_2, opts, &block) attr_names_match = node_1.name == node_2.name ignore_attrs = opts[ :ignore_attr_values ] if ignore_attrs && (ignore_attrs.empty? || ignore_attrs.include?( node_1.name )) attr_names_match else attr_names_match && (node_1.value == node_2.value) end end |
.compare_cdata(node_1, node_2, opts, &block) ⇒ Object
91 92 93 |
# File 'lib/equivalent-xml.rb', line 91 def compare_cdata(node_1, node_2, opts, &block) node_1.text == node_2.text end |
.compare_children(node_1, node_2, opts, &block) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/equivalent-xml.rb', line 95 def compare_children(node_1, node_2, opts, &block) if ignore_content?(node_1, opts) # Stop recursion and state a match on the children result = true else nodeset_1 = as_nodeset(node_1.children, opts) nodeset_2 = as_nodeset(node_2.children, opts) result = self.compare_nodesets(nodeset_1,nodeset_2,opts,&block) end if node_1.respond_to?(:attribute_nodes) attributes_1 = node_1.attribute_nodes attributes_2 = node_2.attribute_nodes result = result && self.compare_nodesets(attributes_1,attributes_2,opts,&block) end result end |
.compare_documents(node_1, node_2, opts, &block) ⇒ Object
62 63 64 |
# File 'lib/equivalent-xml.rb', line 62 def compare_documents(node_1, node_2, opts, &block) self.equivalent?(node_1.root,node_2.root,opts,&block) end |
.compare_elements(node_1, node_2, opts, &block) ⇒ Object
66 67 68 |
# File 'lib/equivalent-xml.rb', line 66 def compare_elements(node_1, node_2, opts, &block) (node_1.name == node_2.name) && self.compare_children(node_1,node_2,opts,&block) end |
.compare_nodes(node_1, node_2, opts, &block) ⇒ Object
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 |
# File 'lib/equivalent-xml.rb', line 31 def compare_nodes(node_1, node_2, opts, &block) result = nil if [node_1, node_2].any? { |node| not node.respond_to?(:node_type) } result = node_1.to_s == node_2.to_s elsif (node_1.class != node_2.class) or self.same_namespace?(node_1,node_2) == false result = false else case node_1.node_type when Nokogiri::XML::Node::DOCUMENT_NODE result = self.compare_documents(node_1,node_2,opts,&block) when Nokogiri::XML::Node::ELEMENT_NODE result = self.compare_elements(node_1,node_2,opts,&block) when Nokogiri::XML::Node::ATTRIBUTE_NODE result = self.compare_attributes(node_1,node_2,opts,&block) when Nokogiri::XML::Node::CDATA_SECTION_NODE result = self.compare_cdata(node_1,node_2,opts,&block) when Nokogiri::XML::Node::TEXT_NODE result = self.compare_text(node_1,node_2,opts,&block) else result = self.compare_children(node_1,node_2,opts,&block) end end if block_given? block_result = yield(node_1, node_2, result) if block_result.is_a?(TrueClass) or block_result.is_a?(FalseClass) result = block_result end end return result end |
.compare_nodesets(nodeset_1, nodeset_2, opts, &block) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/equivalent-xml.rb', line 113 def compare_nodesets(nodeset_1, nodeset_2, opts, &block) local_set_1 = nodeset_1.dup local_set_2 = nodeset_2.dup if local_set_1.length != local_set_2.length return false end local_set_1.each do |search_node| found_node = local_set_2.find { |test_node| self.equivalent?(search_node,test_node,opts,&block) } if found_node.nil? return false else if search_node.is_a?(Nokogiri::XML::Element) and opts[:element_order] if search_node.parent.elements.index(search_node) != found_node.parent.elements.index(found_node) return false end end local_set_2.delete(found_node) end end return local_set_2.length == 0 end |
.compare_text(node_1, node_2, opts, &block) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/equivalent-xml.rb', line 83 def compare_text(node_1, node_2, opts, &block) if opts[:normalize_whitespace] node_1.text.strip.gsub(/\s+/,' ') == node_2.text.strip.gsub(/\s+/,' ') else node_1.text == node_2.text end end |
.equivalent?(node_1, node_2, opts = {}) {|n1, n2, result| ... } ⇒ Boolean
Determine if two XML documents or nodes are equivalent
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/equivalent-xml.rb', line 19 def equivalent?(node_1, node_2, opts = {}, &block) opts = DEFAULT_OPTS.merge(opts) if [node_1, node_2].any? { |node| node.is_a?(Nokogiri::XML::NodeSet)} self.compare_nodesets(as_nodeset(node_1, opts), as_nodeset(node_2, opts), opts, &block) else # Don't let one node to coerced to a DocumentFragment if the other one is a Document node_2 = Nokogiri::XML(node_2) if node_1.is_a?(Nokogiri::XML::Document) and !node_2.is_a?(Nokogiri::XML::Node) node_1 = Nokogiri::XML(node_1) if node_2.is_a?(Nokogiri::XML::Document) and !node_1.is_a?(Nokogiri::XML::Node) self.compare_nodes(as_node(node_1), as_node(node_2), opts, &block) end end |
.same_namespace?(node_1, node_2) ⇒ Boolean
Determine if two nodes are in the same effective Namespace
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/equivalent-xml.rb', line 142 def same_namespace?(node_1, node_2) args = [node_1,node_2] # CharacterData nodes shouldn't have namespaces. But in Nokogiri, # they do. And they're invisible. And they get corrupted easily. # So let's wilfully ignore them. And while we're at it, let's # ignore any class that doesn't know it has a namespace. if args.all? { |node| not node.respond_to?(:namespace) } or args.any? { |node| node.is_a?(Nokogiri::XML::CharacterData) } return true end href1 = node_1.namespace.nil? ? '' : node_1.namespace.href href2 = node_2.namespace.nil? ? '' : node_2.namespace.href return href1 == href2 end |