2012-01-09 76 views
4

我正試圖將我的一個類用DOM進行解析,其中有大量的XPath表達式到SAX解析。 DOM解析對我來說很好,但是我嘗試解析的一些文件太大,導致服務器超時。我希望重用XPathSAX解析,但我不知道是否有可能,如果沒有可能的,你可以請幫助我,因爲我不知道下面的代碼怎麼會當我只有SAX使用:SAX解析器可以在Java中使用XPath嗎?

Document doc = bpsXml.getDocument(); 
String supplierName = BPSXMLUtils.getXpathString(doc, "/Invoice/InvoiceHeader/Party[@stdValue='SU']/Name/Name1"); 
String language = BPSXMLUtils.getXpathString(doc, "/Invoice/InvoiceHeader/InvoiceLanguage/@stdValue"); 
+0

等等,你爲什麼要從XPath轉換到SAX?如果是因爲你是從網絡上獲得的文件和服務器花費的時間太長要發送的文件,然後換你是如何得到該文件,你是不是如何解析它。 – cdeszaq 2012-01-09 16:34:18

+0

還有這[相關SO帖子](http://stackoverflow.com/q/1863250/777186)。其中幾個答案指的是可用於此的工具和API。 – jogojapan 2012-04-13 02:38:35

回答

4

僅使用SAX解析器不會在內存中構建XML樹的表示形式(這就是爲什麼SAX更具內存效率)。只有遇到新的XML元素時,它纔會觸發「事件」。你將不得不在內存中保存上下文(通常是一堆父元素),以「知道」你在樹中的位置。

由於在內存中沒有樹,所以無法使用XPath。您只能測試當前的「上下文」(您的手冊管理堆棧)來查詢您的文檔。請記住,SAX解析器只會對您的文件執行一次運行,因此文件中的順序非常重要。

幸運的是,還有其他一些方法,如VTD-XML這是一個在內存中構建XML樹的庫,但只包含結構部分,它不會從文件中提取實際內容,而是根據需要提取內容。與仍然允許XPath的DOM解析器相比,它的內存效率更高。我personnaly在工作中使用這個庫解析約700MB的XML文件(是的,這是瘋了,但它的工作原理,它是非常快)。

+0

這是一個非常不錯的想法,但不工作那麼好,當你有很多做短數據的XML元素的大文件(2+ GB)。在實踐中,你會減少50/60%的所需內存。當你有非常大的文件時,這很好,但還不夠。而如今數據增長的速度越來越快...... – OGrandeDiEnne 2016-02-13 19:48:02

+0

畢竟這些年來,我沒有解析2GB +文件與VTD-XML。它做得很好,記憶也不是問題。你有沒有嘗試過,並有一個不愉快的經歷?你能分享更多的信息嗎? – 2016-02-14 09:45:43

+0

你分配了多少內存(-Xmx)給解析程序? – OGrandeDiEnne 2016-02-14 18:03:42

1

恕我直言,處理XML最簡單的方法是使用XML的Streaming API StAX。它結合了DOM和SAX的優點(並提供更容易的移植給你)。您仍然有一個指向XML元素的光標(如SAX),但是您的代碼將光標向前移動。這給了XML處理代碼變得更加可讀的巨大優勢。它還解決了內存問題,因爲只有當前的XML元素必須保存在內存中。這裏還有一個不錯的tutorial

要還回答你原來的問題:在谷歌很短的搜索結果顯示我有這可能意味着所有的自定義解決方案是不穩健,不維護,不經過充分測試的不容易的,被廣泛接受的方式。

0

切換到SAX解析(或StAX)將需要您的方法完全更改。它看起來好像你還沒有充分意識到它將會有多少工作。對於任何有意義的建議,我們都需要知道文件有多大,以及您想要對數據進行什麼樣的處理。如果你是過濾數據,例如,然後使用文檔投影XQuery實現可能是一個很好的答案(這將自動使用SAX幕後打造只含有你真正感興趣的數據子集的樹) 。