2011-01-12 29 views
9

那麼很多關於在C++中解析XML的問題等等...... 但是,我的代碼非常具體,而不是一般問題。使用C++進行高性能的XML解析

我要求一個非常有效的C++解析器。特別是我有一個非常非常大的XML文件來解析。 我的應用程序必須打開這個文件並檢索數據。它還必須插入新的節點並將最終結果保存在文件中。

爲此,我在開始時使用了rapidxml,但它需要我打開文件,將其全部解析(所有內容,因爲此lib沒有函數直接訪問文件,而無需首先加載整個樹) ,然後編輯該樹,對其進行修改並通過覆蓋該文件將最終樹存儲在該文件上......它消耗的資源太多。

是否有XML解析器不需要我加載整個文件,但是我可以用它快速插入新節點並檢索數據?你能指出我的這個問題的解決方案嗎?

+5

「高性能xml」 - 是不是一個矛盾? – 2011-01-12 21:21:50

+1

:)以及它可能是... – Andry 2011-01-12 22:17:15

+0

從這個網站的創建者之一,爲什麼XML不是一個數據庫:http://www.joelonsoftware.com/articles/fog0000000319.html – MSalters 2011-01-13 09:17:06

回答

10

您需要一個流式XML解析器而不是所謂的DOM解析器。

流式解析器有兩種類型:拉和推。拉解析器對於快速編寫將數據加載到程序存儲器的XML解析器非常有用。推式解析器適合編寫程序來將一個文檔翻譯爲另一個文檔(這正是您要實現的目標)。因此,我認爲推式解析器對您的問題最適合。

爲了使用推式解析器,您需要編寫實質上是用於解析事件的事件處理程序。通過「解析事件」,我的意思是「達到開始標記」,「達到結束標記」,「找到文本」,「屬性解析」等事件。

我建議您在閱讀文檔時,將轉換後的文檔轉換爲單獨的臨時文件。因此,您的XML解析事件處理程序需要寫入,以便它們是有狀態的,並逐漸寫出翻譯文檔的XML。

用於C++的三個優秀的推送解析器庫包括Expat,Xerces-C++libxml2

2

我確信沒有XML庫存在允許您在不加載它的情況下修改文件。這是不可能的,因爲文件不能這樣工作:不能在文件中插入(或刪除)。你只能用覆蓋一個相同大小的塊,或者最後加上。但是您的請求需要在文件中間添加或刪除。

只讀XML文件的一部分可能是可能的。但寫作 ...沒辦法。

+0

嗯沒有......它是可能的排序是不需要的,稍後執行它,通過標記文件,您可以找到一個節點,並在其中插入新節點...無需獲取整個文件...不是? – Andry 2011-01-12 21:05:52

+1

@Andry:錯的。在XML文件中需要排序*。您可能不需要它,但XML標準要求節點的排序是固定的。此外,標記(特別是找到匹配的* end *標記)幾乎涉及讀取整個文件。 – 2011-01-12 21:09:53

5

搜索「SAX解析器」。它們大多是標記器,即它們通過標記發出標記而不構建樹。

3

SAX解析器比DOM解析器快,因爲DOM解析器在構建XML文檔的內存中表示之前將整個文件讀入內存,而SAX解析器的行爲類似於事件偵聽器,並且在讀入文檔時構建文檔文件。 Go here獲得解釋。

正如你所說的Xerces是一個很好的C++ SAX解析器。

我建議尋找將XML文檔分解爲更小的XML文檔的方法,因爲這似乎是您的問題的一部分。

2

好的,這裏有一條非常具有吸引力的曲目,我看了一下,但並沒有真正使用過它,它叫做asmxml。這些男孩聲稱性能沒有問題,缺點是,你需要x86彙編器。

1

如果您確實需要高性能XML流解析器那麼libhpxml很可能是您的正確選擇。

0

儘可能的去尋找模板庫,比如Boost :: property_tree或者Boost :: XMLParser或者POCO :: XML,並且Folly裏面有XML Parser。

避免舊的C庫,它都是舊的代碼設計。

-1

有人說QtXML模塊對於巨大的XML文件來說是高性能的。