我正在使用libxml2解析html文档,并删除了一些基于xpath查询的元素。例如,我想使用以下命令删除所有包含“ display:none”的元素:
stripNode(doc, "//*[contains(@style,'display:none')]");
...
public static void stripNode(Html.Doc* doc, string xpath)
{
Xml.XPath.Context cntx = new Xml.XPath.Context(doc);
Xml.XPath.Object* res = cntx.eval_expression(xpath);
if(res != null
&& res->type == Xml.XPath.ObjectType.NODESET
&& res->nodesetval != null)
{
for(int i = 0; i < res->nodesetval->length(); ++i)
{
Xml.Node* node = res->nodesetval->item(i);
if(node != null)
{
node->unlink();
node->free_list();
}
}
}
delete res;
}
但是我碰到了文档中另一个元素为“ display:none”的文档,而另一个元素为“ display:none”。现在,当顺序较高的元素取消链接并释放时,其所有子元素也消失了。但是第二个元素仍然是“ res”的一部分,而不是“ null”。所以我因为双重自由而崩溃。
有没有一种方法可以检查节点是否仍然是文档的一部分或已经释放。或者,是否有一种方法可以只查找xpath-query的第一个匹配项,然后在取消链接和释放节点后寻找下一个匹配项?
我想执行
cntx.eval_expression(xpath);
在每个未链接的节点之后再次运行会非常缓慢。
谢谢您的帮助 :)
最佳答案
我建议另一种方法来达到相同的效果。您可以使用更特定的xpath,以便在嵌套元素的style
属性包含"display:none"
的情况下,仅选择最外面的元素:
//*[contains(@style,'display:none')][not(ancestor::*[contains(@style,'display:none')])]
关于memory-management - libXML:检查节点是否已经取消链接并释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30585465/