libxml ++ TextReader;跳过节点

时间:2016-10-06 08:34:06

标签: xml libxml2 saxparser xmltextreader

我使用libxml ++来解析一个相当大的XML文件,因此无法使用DOM。

假设我有一个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 个答案:

答案 0 :(得分:2)

我可能找到(部分)解决方案。

而read()读取下一个节点,因此进入更深层次的节点。 layers,next()跳转到当前深度的下一个节点。调用read()两次会将阅读器移动到第一本书的开头标记(深度1)。现在调用next()会使读者跳转到深度为1的下一个节点,在本例中为结束标记。现在可以通过调用next()来遍历所有书籍,因为如果没有更多深度为1的节点,它将返回false。

不幸的是,没有选项可以将阅读器移到树上,所以如果你在循环中调用read()并移动到更深的层,next()将跳转到该层的下一个节点,在大多数情况下,这可能不是一个令人满意的答案。

另一种方法是在阅读器上调用get_current_node(),然后使用get_children()来检索直接子节点的列表。 在这个例子中,可以调用read()将阅读器移动到根节点,然后分别调用get_current_node()和get_children并迭代结果列表中的&#39; book&#39;节点。

这似乎只适用于小文件,因为调用get_children()一个包含许多子节点的节点可能会导致缩短列表,只显示所有子节点的一小部分

我发现可能的解决方法是导航到所需的深度(如上所述),通过调用next()循环遍历此深度中的节点,并在每个循环之后,通过调用expand()来初始化新的Node-Object TextReader,它扩展当前节点及其所有子树。 这样,您可以通过访问新节点来处理子树,而无需更改TextReader-Object。

但是,要小心。除非你调用free_wrapper(),否则不会删除新节点的C ++ - Wrapper。

来自文档:

  

不会删除C ++包装器。使用此方法(expand())会导致内存   泄漏,除非你调用xmlpp :: Node :: free_wrappers(),否则   打算由应用程序调用。

请注意,这是我自己的观察,因为函数文档非常稀疏或不完整。