2012-06-06 39 views
0

我有點被卡住,不得不使用.Net 2.0,所以LINQ xml不可用,儘管我會對它的比較感興趣...C#(.net 2.0)中的大型XML文件的差異

我不得不編寫一個內部程序來下載,提取和比較一些基本上是構建配置的大型XML文件(每個大約10M)。我第一次試圖使用庫,如Microsoft's XML diff/patch,但比較文件需要2-3分鐘,即使忽略空白,命名空間等(我每次都會忽略一個,試圖找出最快的)。我試圖實現我自己的想法 - XmlDocument對象中的節點列表,根指向直接後代(順便說一句,45000個子項)的鍵的字典,指向int以指示XML文檔中的節點位置......所有至少運行2分鐘。我最後的實現在1-2秒內完成 - 我做了一個系統進程調用,用幾行上下文進行比較,並保存這些結果以顯示(我們的開發機器包括cygwin,謝天謝地)。

我不禁想到有一個更好的,XML的具體方式來做到這一點,就像純文本差異一樣快 - 特別是因爲我真正感興趣的是名稱元素是每個直系後代的孩子,並可能爲了我的目的扔掉文件的4/5(我們只需要知道包含什麼文件,而不涉及任何其他語言或版本)

因此,和XML一樣流行,我敢肯定,那裏有人不得不做類似的事情。什麼是比較這些大型XML的快速高效方法? (prefereably開源或免費)

編輯:節點的樣本 - 我只需要找到丟失的名稱元素(有超過45K節點以及)

<file> 
    <name>SomeFile</name> 
    <version>10.234</version> 
    <countries>CA,US</countries> 
    <languages>EN</languages> 
    <types>blah blah</types> 
    <internal>N</internal> 
</file> 
+0

http://stackoverflow.com/q/655141/102937 –

+0

請提供更多的上下文。你需要什麼樣的輸出?你在尋找什麼樣的差異? – Oded

+0

@羅伯特哈維 - 我已經通過該頁面,沒有運氣 –

回答

0
XmlDocument source = new XmlDocument(); 
source.Load("source.xml"); 
Dictionary<string, XmlNode> files = new Dictionary<string, XmlNode>(); 
foreach(XmlNode file in source.SelectNodes("//file")) 
    files.Add(file.SelectSingleNode("./name").InnerText, file); 

XmlDocument source2 = new XmlDocument(); 
source2.Load("source2.xml"); 
XmlNode value; 
foreach(XmlNode file in source2.SelectNodes("//file")) 
    if (files.TryGetValue(file.SelectSingleNode("./name").InnerText, out value)) 
     // This file is both in source and source2. 
    else 
     // This file is only in source2. 

我不知道正是你想要的,我希望這個例子能幫助你完成你的任務。

+0

我以前曾試過一本字典,但無論出於何種原因,在我的大腦中,我認爲將索引存儲到要使用的節點列表會更高效(無法真正說出原因,在錯誤中過度使用方向我猜)。這花了幾分鐘。給了這個鏡頭 - 效果很好,幾乎和純文本差不多一樣快。不知道爲什麼我不考慮存儲對實際節點的引用,而不是... –

0

Diffing XML可以通過多種方式完成。不過,您對細節的描述並不十分具體。發生什麼事是文件很大,你只需要4/5的信息。

好,那麼算法如下:

  • 規範和減少文件的事項的信息。
  • 保存結果。
  • 比較結果。

而且實施

  • 使用XmlReader API,這是有效的,產生你的信息明文表示。爲什麼純文本表示?因爲diff工具是基於純文本的假設。我們的眼球也是如此。爲什麼XmlReader?你可以使用SAX,這是內存效率,但XmlReader更有效。至於那個純文本文件的確切規格......你只是沒有包含足夠的信息。
  • 將純文本文件保存到某個臨時目錄。
  • 使用像GnuWin32 diff這樣的命令行diff工具來獲取一些差異輸出。是的,我知道,不是純粹而恰當的,但是可以開箱即用,並且不需要編碼。如果你熟悉一些C#diff API(我不是),那麼當然,那麼就使用那個API。
  • 刪除臨時文件。 (或者可選擇保留它們,如果你打算重複使用它們)。
+0

是的,這就是我迄今爲止所做的,它工作得很好,只是希望比純文本差異更「XML」的方式 –

+0

@DrakeClarris,這裏的關鍵洞察是XML和diff輸出根本不匹配和結婚。這就是爲什麼希望採用更多XML的方式做事沒有意義。你可能也希望更有角度的滾動輪子。 – Lumi