2009-09-15 20 views
11

显然我需要(a)将这两个字符串转换为canonical XML或(b)比较它们的分析树。以下内容不起作用,因为返回的文档对象没有明确的==定义。如何在Ruby中测试XML相等性?

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,所以我宁愿坚持下去,但我会使用任何库工程。

+2

我想看到一个很好的答案。 AFAIK,规范XML是你此刻的唯一选择。 – Swanand 2009-09-16 17:29:23

+0

[diff a ruby​​ string or array]可能的重复(http://stackoverflow.com/questions/80091/diff-a-ruby-string-or-array) – sawa 2011-05-23 08:24:03

回答

4

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

1

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

Nokogiri没有任何东西可以为你做;你必须自己构建它。亚伦帕特森discusses some of the issues here

至于XML文档 关注,没有任何两个节点是有史以来 相等。文档中的每个节点都是 不同。每个节点有多个 属性可供比较:

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

考虑在 同一文档中添加两个节点。他们可以从来没有有 相对于兄弟 节点相同的位置,因此 文件中的两个节点不能“相等”。

可以然而比较两个 不同的文件。但你需要 回答这7个问题你自己 你走在两棵树。您对 的相同要求可能与其他人不同 。

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

+4

我很肯定规范的XML(http:// www.w3.org/TR/xml-c14n)负责所有这些问题。 – 2009-09-16 02:30:30

11

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

我更喜欢equivalent-xml,因为它提供了更多的灵活性(可能以严格为代价),允许您比较是否考虑元素顺序或空白。

+0

加上equivalent-xml提供了RSpec匹配器。 – 2016-07-26 20:03:09