xpath:排除属于属性值的文本

时间:2013-07-28 17:54:11

标签: php xpath

我需要解析一大块html,寻找一个特定的术语,并将该术语的所有实例都包含在A标签中(带有“关键字”类)。

要做到这一点,我使用xpath解析html位,它运行良好......

$nodes = $xpath->query('//text()[contains(., "CLEA")]');

除了在极少数情况下,术语在属性值中,在这种情况下会发生一些递归并且html会中断:

Hello <a class="tag" title="this is <a class="tag" href="#">CLEA</a>">CLEA</a>, hello!

当我想要的是

Hello <a class="tag" title="this is CLEA">CLEA</a>, hello!

我正在努力纠正我的xpath查询,以排除属于属性值的文本。

非常感谢您的帮助,谢谢。

以下是使用Xpath解析的html示例:

<?xml version="1.0" encoding="UTF-8"?>
<p>
Carte Blanche aux Artistes du <a class="tag" href="?tag=clea" rel="tag-definition" title="Click here to learn more about CLEA">CLEA</a>
14.01 - 19.01.2013
at: 
Gare Numérique de Jeumont, France
Organised by:
DRAC, Nord-Pas de Calais
Education National Nord-Pas de Calais
In the context of :
CLEA, résidence-mission
Contrat Local d'Education Artistique
http://cleavaldesambre.wordpress.com/
With: Martin Mey, Stephane Querrec, Woudi Tat, Marie Morel, LAb[au]
LAb[au] featured projects: <a title="Click here to learn more about f5x5x1" href="?tag=f5x5x1" rel="tag-definition" class="tag">Framework f5x5x1</a>, kinetic light art installation
<a title="Click here to learn more about binary waves" href="?tag=binary+waves" rel="tag-definition" class="tag">binary waves</a>, cybernetic light art installation</p>

更新2 xpath在像这样的

中使用
    $dom = new DOMDocument('1.0', 'utf8');
    $dom->formatOutput = true;
    $dom->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'));
    $xpath = new DOMXPath($dom);
    foreach ($tags as $t) {
        $label = $t['label'];
        $nodes = $xpath->query('//text()[contains(., "' . $label . '")]');
        $urlVersion = htmlentities(urlencode($label));

        foreach ($nodes as $node) {
            $link = '<a class="tag" rel="tag-definition" title="Click to know more about ' . $label . '" href="?tag='.$urlVersion.'">'.$label.'</a>';
            $replaced = str_replace($label, $link, $node->textContent);
            $newNode = $dom->createDocumentFragment();
            $newNode->appendChild(new DOMText($replaced));
            $node->parentNode->replaceChild($newNode, $node);
        }
    }

    $text= $dom->saveHTML();

发生错误是因为一个标签是“les amis de CLEA”而另一个标签是“CLEA”。

1 个答案:

答案 0 :(得分:1)

该表达式不应返回属性值。这看起来像是PHP XPath实现中的一个错误。在Xpath中,///descendant-or-self::node()/的缩写。后代不包含属性。即使他们这样做,text()没有轴也是child::text()的缩写,属性没有子节点。 http://www.w3.org/TR/xpath/#axes

所以你需要一个解决方法。您正在使用的完全展开的表达式为/descendant-or-self::node()/child::text()[contains(., "CLEA")]。所以让我们试着调整一下。而不是node(),请尝试*,它只匹配元素:

/descendant-or-self::*/text()[contains(., "CLEA")]

或者尝试直接在text()轴上使用descendant-or-self节点测试:

/descendant-or-self::text()[contains(., "CLEA")]