1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
require 'nokogiri'
require 'tdiff'
class Nokogiri::XML::Node
include TDiff
include TDiff::Unordered
#
# Compares the XML/HTML node with another.
#
# @param [Nokogiri::XML::Node] node
# The other XMl/HTML node.
#
# @return [Boolean]
# Specifies whether the two nodes are equal.
#
def tdiff_equal(node)
if (self.class == node.class)
case node
when Nokogiri::XML::Attr
(self.name == node.name && self.value == node.value)
when Nokogiri::XML::Element, Nokogiri::XML::DTD
self.name == node.name
when Nokogiri::XML::Text, Nokogiri::XML::Comment
self.text == node.text
when Nokogiri::XML::ProcessingInstruction
(self.name == node.name && self.content = self.content)
else
false
end
else
false
end
end
#
# Enumerates over the children of another XML/HTML node.
#
# @param [Nokogiri::XML::Node] node
# The other XMl/HTML node.
#
# @yield [child]
# The given block will be passed every child of the node.
#
# @yieldparam [Nokogiri::XML::Node] node
# A child node.
#
def tdiff_each_child(node,&block)
if node.kind_of?(Nokogiri::XML::Element)
node.attribute_nodes.sort_by(&:name).each(&block)
end
node.children.each(&block)
end
#
# Finds the differences between the node and another node.
#
# @param [Nokogiri::XML::Node] other
# The other node to compare against.
#
# @param [Hash] options
# Additional options for filtering changes.
#
# @option options [Boolean] :added
# Yield nodes that were added.
#
# @option options [Boolean] :removed
# Yield nodes that were removed.
#
# @yield [change, node]
# The given block will be passed each changed node.
#
# @yieldparam [' ', '-', '+'] change
# Indicates whether the node stayed the same, was removed or added.
#
# @yieldparam [Nokogiri::XML::Node] node
# The changed node.
#
# @return [Enumerator]
# If no block was given, an Enumerator object will be returned.
#
def diff(other,options={},&block)
return enum_for(__method__,other,options) unless block
if (options[:added] || options[:removed])
tdiff_unordered(other) do |change,node|
if (change == '+' && options[:added]) then yield change, node
elsif (change == '-' && options[:removed]) then yield change, node
end
end
else
tdiff(other,&block)
end
end
end
|