libxml ++ TextReader;跳过节点

问题描述:

我正在使用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()'方法。你可以发布你的解决方案作为答案?你可以在*上[回答你自己的问题](http://*.com/help/self-answer)。 – nwellnhof

+0

你好@nwellnhof, 我编辑了我的问题,并将可能的解决方案移到了答案中。 但是,这两种解决方案都可能不适合,具体取决于用户。 对于我来说,我需要解析一个大的(〜600mb)XML文件,因此所提出的解决方案可能会帮助大多数人,但他们仍然不能满足我的需求。 什么是最好的显示方式,我的问题只是部分回答? –

+1

您的答案中已经提到它可能不适合每个人的需求。海事组织,你的答案绝对够好。你也可以在48小时内[接受你自己的答案](http://blog.*.com/2009/01/accept-your-own-answers/)。但是如果你希望得到更好的答案,你可以选择不这样做。 – nwellnhof

我可能找到(部分)解决方案。然而,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(),而不是 ,否则使用此方法(展开())会导致内存泄漏,原因是应用程序将调用此非 。


注意,这是从我自己的观察,作为功能单证是很稀疏或不完整。