2009-09-15 17 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