equivalent-xml

Description

Problem

Testing XML output is difficult:

  • Comparing text output is brittle due to the vagaries of serialization.

  • Attribute order doesn’t matter.

  • Element order matters sometimes, but not always.

  • Text sometimes needs to be normalized, but CDATA doesn’t.

  • Nodes in the same namespace don’t always use the same prefix

  • Etc.

Solution

EquivalentXml for Nokogiri

Use

EquivalentXml.equivalent?(node_1, node_2, opts = { :element_order => false, :normalize_whitespace => true })

node_1 and node_2 can be any Nokogiri::XML::Node descendants. The most common use is to compare two Nokogiri::XML::Document instances.

node_1 is equivalent to node_2 if and only if:

  • node_1 and node_2 are of the same class

  • node_1 and node_2 are in the same namespace

  • node_1 and node_2 have the same number of child nodes (excluding ProcessingInstructions, Comments and empty Text nodes)

  • For each child of node_1, there is exactly one equal child of node_2

  • If called with :element_order => true, equivalent child elements must be in the same relative position in order to be considered equal

Element nodes are equivalent if they have the same name, and their child nodesets are equal (as defined above)

Attribute nodes are equivalent if their names and values match exactly

CDATA nodes are equivalent if their text strings match exactly, including leading, trailing, and internal whitespace

Non-CDATA CharacterData nodes are equivalent if their text strings match after stripping leading and trailing whitespace and collapsing internal whitespace to a single space

Document nodes are equivalent if their root nodes are equal

ProcessingInstruction and Comment nodes are ignored

Options

:element_order => true

Require elements to be in the same relative position in order to be considered equivalent.

:normalize_whitespace => false

Don’t normalize whitespace within text nodes; require text nodes to match exactly.

Contributing to equivalent-xml

  • Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet

  • Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it

  • Fork the project

  • Start a feature/bugfix branch

  • Commit and push until you are happy with your contribution

  • Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Copyright © 2011 Michael B. Klein. See LICENSE.txt for further details.