2016-10-06 68 views
1

我正在使用libxml ++來分析一個相當大的XML文件,因此無法使用DOM。libxml ++ TextReader;跳過節點

說我有一個XML文件,如:

<?xml version="1.0"?> 

<root> 

    <book name="book1"> 
    <chapter name="chapter1"> 
     #Pages 
    </chapter> 
    <chapter name="chapter2"> 
     #Pages 
    </chapter> 
    </book> 

    <book name="book2"> 
    <chapter name="chapter1"> 
     #Pages 
    </chapter> 
    <chapter name="chapter2"> 
     #Pages 
    </chapter> 
    </book> 

    <book name="book3"> 
    <chapter name="chapter1"> 
    </chapter> 
     #Pages 
    <chapter name="chapter2"> 
     #Pages 
    </chapter> 
    </book> 

</root> 

有沒有辦法來遍歷所有的書籍,而不必處理與使用TextReader的嵌套節點? SAX解析器一般可以嗎?

編輯: 移動答案解答。

+1

是的,它是您正在尋找的'next()'方法。你可以發佈你的解決方案作爲答案?你可以在StackOverflow上[回答你自己的問題](http://stackoverflow.com/help/self-answer)。 – nwellnhof

+0

你好@nwellnhof, 我編輯了我的問題,並將可能的解決方案移到了答案中。 但是,這兩種解決方案都可能不適合,具體取決於用戶。 對於我來說,我需要解析一個大的(〜600mb)XML文件,因此所提出的解決方案可能會幫助大多數人,但他們仍然不能滿足我的需求。 什麼是最好的顯示方式,我的問題只是部分回答? –

+1

您的答案中已經提到它可能不適合每個人的需求。海事組織,你的答案絕對夠好。你也可以在48小時內[接受你自己的答案](http://blog.stackoverflow.com/2009/01/accept-your-own-answers/)。但是如果你希望得到更好的答案,你可以選擇不這樣做。 – nwellnhof

回答

1

我可能找到(部分)解決方案。然而,read()讀取下一個節點,因此移動到「更深」層,next()跳轉到當前深度的下一個節點。調用read()兩次將閱讀器移動到第一本書的開始標籤(深度1)。現在調用next()會使讀者跳到深度爲1的下一個節點,在這種情況下是結束標記。現在可以通過調用next()來遍歷所有書籍,因爲如果沒有深度爲1的節點,它將返回false。

不幸的是,沒有選項可以將讀者移到樹上,所以如果你在循環內調用read()並移動到更深層,next()將跳轉到該層上的下一個節點,因此在大多數情況下這可能不是一個令人滿意的答案。


另一種方法是調用get_current_node()讀取器上,然後使用get_children()來檢索直接子節點的列表。 在這個例子中,我們可以調用read()來移動閱讀器到根節點,然後分別調用get_current_node()和get_children並迭代'book'節點的結果列表。

這似乎只適用於小文件,因爲調用get_children()具有許多子節點的節點可能會導致縮短的列表,只顯示所有子節點的一小部分


可能的解決方法,我發現是導航到所需的深度(如上所述),循環遍歷該深度的節點通過調用next()和每個循環後,通過調用初始化一個新的節點對象在TextReader上展開(),展開當前節點及其所有子樹。 這樣,您可以通過訪問新節點來處理子樹,而無需更改TextReader對象。

但是,要小心。新節點的C++ - Wrapper不會被刪除,除非您調用free_wrapper()。

從文檔:

的C++包裝不會被刪除。除非調用xmlpp :: Node :: free_wrappers(),而不是 ,否則使用此方法(展開())會導致內存泄漏,原因是應用程序將調用此非 。


注意,這是從我自己的觀察,作爲功能單證是很稀疏或不完整。