我正在使用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()读取下一个节点并因此进入“更深”的层,而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上调用expand()初始化一个新的Node-Object,这将扩展当前节点及其所有子树。这样,您可以通过访问新节点来在子树上工作,而无需更改TextReader-Object。
但是,要小心。除非您调用free_wrapper(),否则不会删除新节点的C ++包装器。
从文档中:
C ++包装器不会被删除。使用此方法(expand())会导致内存泄漏,除非您调用xmlpp :: Node :: free_wrappers(),但应用程序不打算调用它。
请注意,这是根据我自己的观察得出的,因为功能文档非常稀疏或不完整。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句