libxml++ 文本阅读器;跳过节点

libxml++ TextReader; Skipping nodes

我正在使用 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 解析器可以吗?

编辑: 移动解决方案来回答。

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

而 read() 读取下一个节点并因此移动到 'deeper' 层,而 next() 跳转到当前深度的下一个节点。调用 read() 两次将 reader 移动到第一本书的开始标签(深度 1)。现在调用 next() 会导致 reader 跳转到深度为 1 的下一个节点,在本例中为结束标记。现在可以通过调用 next() 遍历所有书籍,因为如果没有更多深度为 1 的节点,它将 return false

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


另一种方法是在 reader 上调用 get_current_node(),然后使用 get_children() 检索直接子节点的列表。 在此示例中,可以调用 read() 将 reader 移动到根节点,然后分别调用 get_current_node() 和 get_children 并遍历 'book' 的结果列表节点。

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


我发现的一个可能的解决方法是导航到所需的深度(如上所述),通过调用 next() 在该深度的节点上循环,并在每次循环之后,通过调用 expand( ) 在 TextReader 上,它展开当前节点及其所有子树。 这样您就可以通过访问新节点来处理子树,而无需更改 TextReader 对象。

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

来自文档:

The C++ wrappers are not deleted. Using this method (expand()) causes memory leaks, unless you call xmlpp::Node::free_wrappers(), which is not intended to be called by the application.


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