我使用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解析器?
修改 移动解决方案回答。
答案 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(),否则 打算由应用程序调用。
请注意,这是我自己的观察,因为函数文档非常稀疏或不完整。