如何使用 libxml2 过滤掉节点

问题描述

给定一个 XML 文档和一个 XPath 表达式,我想创建一个新文档,该文档具有原始文档的所有节点除了 XPath 表达式选择的节点,有效地给出减法过滤器的结果。

我的想法是使用 xmlXpathEvalExpression() 函数,并且对于根文档树中的每个节点,复制该节点,除非该节点与返回的 xmlNodeSet 匹配。然而,libxml2 没有给出关于如何或者甚至是否可以测试节点是否相等的提示

您是否应该比较指向返回集合中节点的指针?或者你应该比较给定的节点名称/命名空间?

解决方法

正如评论中提到的,从计算 XPath 表达式返回的节点指针直接指向原始文档中的节点。[1] 所以你可以简单地对每个节点调用 xmlUnlinkNode返回的节点集中的节点以将其从文档中删除。然后,在第二步中,在每个节点上调用 xmlFreeNode 以释放节点。在所有节点都取消链接之前不要调用 xmlFreeNode 很重要。[2]

[1] 除了从命名空间轴 namespace::* 返回的类型为 XML_NAMESPACE_DECL 的命名空间节点外,但这些节点很少使用。

[2] 如果您以相反的顺序迭代节点集,它应该可以立即释放每个节点。