2009-01-02 62 views
17

我需要在C#中對相當大的XML文件進行一些處理(這裏可能大於千兆字節),包括執行一些複雜的xpath查詢。我遇到的問題是,我通常會通過System.XML庫執行此操作的標準方式喜歡在執行任何操作之前將整個文件加載到內存中,這可能會導致此大小的文件出現內存問題。如何最好地在.NET中使用XPath與非常大的XML文件?

我不需要更新文件,只需讀取它們並查詢其中包含的數據即可。一些XPath查詢涉及很多層次的父子關係 - 我不確定這是否會影響使用流讀取器的能力,而不是將數據作爲塊加載到內存中。

我可以看到使它工作的一種方式是使用基於流的方法執行簡單分析,也許將XPath語句包裝成XSLT轉換,然後我可以在文件之間運行這些轉換,雖然看起來有些複雜。

或者我知道有一些XPath查詢不會運行的元素,所以我想我可以根據它的原始樹結構將文檔分解成一系列較小的碎片,這可能足夠小在內存中進程不會造成太大的破壞。

我試圖在這裏解釋我的目標,所以如果我在一般方法方面吠叫完全錯了,我相信你的鄉親可以設置我的權利......

回答

0

有你一直在努力XPathDocument中? 該類針對有效處理XPath查詢進行了優化。

如果您無法使用XPathDocument有效處理輸入文檔,則可以考慮使用XmlReader預處理和/或分割輸入文檔。

1

你已經概述了你的選擇。

要麼您需要放棄XPath並使用XmlTextReader,要麼您需要將文檔分解爲可以使用XPath的可管理塊。

如果您選擇後者,請使用XPathDocument,它的只讀限制允許更好地使用內存。

1

爲了使用標準.NET類執行XPath查詢,需要將整個文檔樹加載到內存中,如果花費高達千兆字節可能不是一個好主意。恕我直言,XmlReader是一個很好的類處理此類任務。

+0

XPathDocument也是一個輕量級的課程。 – 2009-01-02 17:06:28

+2

XPathDocument的問題是整個文檔將被加載到內存中。 – 2009-01-02 17:10:37

1

看起來您已經嘗試過使用XPathDocument,並且無法容納內存中已解析的xml文檔

如果是這種情況,那麼在開始分割文件之前(這最終是正確的決定!),您可以嘗試使用XSLT/XQuery處理器Saxon。它在加載的XML文檔("tinytree" model)中具有非常高效的內存中表示形式。另外Saxon SA(shema-aware版本,這不是免費的)有some streaming extensions。閱讀更多關於here

1

如何將整個事物讀入數據庫然後使用臨時數據庫?這可能會更好,因爲使用TSQL可以更高效地完成查詢。

+0

另一個選擇可能是創建一個帶有數據類的通用列表。 用xml數據填充它,然後用linq查詢它。我最近做了很多事,而且效果非常好。 – 2009-01-05 13:57:12

2

技嘉XML文件!我不羨慕你這個任務。

有什麼辦法可以更好地發送文件?例如。它們是通過網絡發送給你的 - 如果它們是更高效的格式,對所有相關方而言可能會更好。將文件讀入數據庫不是一個壞主意,但確實可能非常耗時。

我不會嘗試通過讀取整個文件在內存中完成所有操作 - 除非您有64位操作系統和大量內存。如果文件變爲2,3,4GB會怎麼樣?

另一種方法是讀取XML文件並使用SAX解析文件並根據某些邏輯分割寫出較小的XML文件。您可以使用XPath處理這些。我在20-30MB文件上使用XPath,速度非常快。我本來打算使用SAX,但認爲我會給XPath一個去,並且很驚訝它有多快。我節省了大量的開發時間,可能每個查詢只損失250ms。我使用Java進行解析,但我懷疑在.NET中幾乎沒有什麼區別。

我讀過XML :: Twig(一個Perl CPAN模塊)是爲了處理基於SAX的XPath解析而明確編寫的。你可以使用不同的語言嗎?

這也可能有助於https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-1044772.html

1

我認爲最好的辦法就是讓自己的XML解析器,可以閱讀小塊不是整個文件,也可以將大文件分割成小文件和使用DOTNET班,這些文件。 問題是你不能解析一些數據,直到整個數據可用,所以我建議使用你自己的解析器,而不是dotnet類

9

XPathReader是答案。它不是C#運行時的一部分,但可以從Microsoft下載。這是一個MSDN article

如果使用XmlTextReader構造一個XPathReader,您可以通過XPath表達式的方便性獲得流式讀取的效率。

我還沒有使用它在千兆字節大小的文件上,但我已經在數十兆字節的文件上使用它,這通常足以減慢基於DOM的解決方案。

從下面引用:「XPathReader提供了以流式方式對XML文檔執行XPath的功能」。

Download from Microsoft

0

因爲在你的情況下,數據的大小可以在運行Gbs的有你使用ADO.NET使用XML作爲數據庫考慮。除此之外,內存佔用不會很大。

另一種方法是使用Linq to XML與使用XElementStream等元素。希望這可以幫助。

相關問題