我正在用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;
}
但是我遇到的文件中包含一个&#34; display:none&#34;在另一个元素中使用&#34; display:none&#34;。现在,当顺序中较高的元素被取消链接并释放时,它的所有子节点也都消失了。但第二个元素仍然是&#34; res&#34;并且不是&#34; null&#34;。所以我因双重免费而遭遇崩溃。
有没有办法检查节点是否仍然是文档的一部分或已经释放。或者,有没有办法只查找xpath查询的第一个匹配项,并在取消链接和释放节点后查找下一个匹配项? 我想执行
cntx.eval_expression(xpath);
在每个未链接的节点之后再次非常慢。
感谢您的帮助:)
答案 0 :(得分:3)
我建议另一种方法来实现同样的目标。您可以使用更具体的xpath,以便在嵌套元素包含style
属性包含"display:none"
的情况下,只有最外层元素被选中:
//*[contains(@style,'display:none')][not(ancestor::*[contains(@style,'display:none')])]