libXML:检查节点是否已取消链接并释放

时间:2015-06-02 00:25:36

标签: memory-management xpath libxml2 vala

我正在用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);

在每个未链接的节点之后再次非常慢。

感谢您的帮助:)

1 个答案:

答案 0 :(得分:3)

我建议另一种方法来实现同样的目标。您可以使用更具体的xpath,以便在嵌套元素包含style属性包含"display:none"的情况下,只有最外层元素被选中:

//*[contains(@style,'display:none')][not(ancestor::*[contains(@style,'display:none')])]