如何在Ruby中测试XML相等性?

显然,我需要(a)将两个字符串转换为规范XML或(b)比较它们的解析树。 以下不起作用,因为返回的文档对象没有合理的==定义。

 Nokogiri.XML(doc_a) == Nokogiri.XML(doc_b) 

下面也没有,因为Nokogiri的to_xml留下了一些内部空白:

 Nokogiri.XML(doc_a).to_xml == Nokogiri.XML(doc_b).to_xml 

这是一个合理的近似平等(并且适用于大多数情况),但它并不完全正确:

 Nokogiri.XML(doc_a).to_xml.squeeze(' ') == Nokogiri.XML(doc_b).to_xml.squeeze(' ') 

我已经在使用Nokogiri了,所以我更愿意坚持下去,但我会使用任何图书馆的作品。

如果您正在寻找结构相等而不关心标签和属性的顺序,那么xml-simple库可能是一个不错的选择。 它将xml转换为ruby的数据结构(散列和列表),可以安全地与==运算符进行比较。

实际上有几个很好的基于Nokogiri的库用于检查XML树的等价性,包括equiv- xml或nokogiri-diff ,这可能会有所帮助。

我更喜欢等效的xml,因为它提供了更多的灵活性(可能以严格为代价?),允许您与元素顺序或空格进行比较或不考虑。

将它们转换为字符串将不会非常成功。 例如,如果一个元素有两个属性,那么顺序真的重要吗? 在大多数情况下,没有。 给定节点的子节点顺序? 取决于你在做什么。 但如果其中一个问题的答案是“不”,那么简单的字符串比较就是充其量的问题。

Nokogiri没有任何东西能为你做这件事; 你必须自己建造它。 Aaron Patterson 在这里讨论了一些问题 :

就XML文档而言,没有两个节点是平等的。 文档中的每个节点都是不同的。 每个节点都有许多要比较的属性:

  1. 这个名字是一样的吗?
  2. 属性怎么样?
  3. 命名空间怎么样?
  4. 孩子的数量怎么样?
  5. 所有的孩子都一样吗?
  6. 它的父节点是否相同?
  7. 它相对于兄弟节点的位置怎么样?

考虑将两个节点添加到同一文档中。 它们永远不会相对于兄弟节点具有相同的位置,因此文档中的两个节点不能“相等”。

但是,您可以比较两个不同的文档。 但是当你走在两棵树上时,你需要自己回答这七个问题。 您对同一性的要求可能与其他要求不同。

这是你最好的选择:走树并进行比较。