DOMXpath查询以获取特定文本

时间:2015-07-04 20:35:50

标签: php xpath domxpath

我需要一个DOMXpath查询来获取特定文本后的标记值。 这是我的代码,但它不起作用

$str= '...............
URL: <a href="http://www.example.com" target="_blank">http://example.com#showtext</a>
            ....................
 ';

    $dom = new DOMDocument;
    @$dom->loadHTML($str);

    $xp = new DOMXPath($dom);
    $links = $xp->query('//[text()="URL: "]following-sibling::a[1]');

    foreach ($links as $link) {
    echo $link->nodeValue . PHP_EOL;

    }
    ?>

我应该在查询中使用follow-sibling还是应该使用它?

1 个答案:

答案 0 :(得分:0)

您正在寻找一个跟在文本节点后面的标记,所以基本上您的xpath查询必须如下所示:

//text()/following-sibling::node()

然后你添加条件:

//text()[contains(., "URL: ")]/following-sibling::node()[1][name(.)="a"]

文本节点的条件仅检查它是否包含"URL: ",但您可以更明确。如果您希望文本节点完全"URL: "[.="URL: "]写为条件。

如果您希望文本节点以"URL: "结尾,则更难,因为xpath没有ends-with函数。所以你必须用PHP编写它,register自己编写它。例如:

function ends_with($node, $needle){
    return substr($node[0]->nodeValue, -strlen($needle)) === $needle;
}

$xp->registerNamespace("php", "http://php.net/xpath");
$xp->registerPHPFunctions("ends_with");

$links = $xp->query('//text()[php:function("ends_with", ., "URL: ")]/following-sibling::node()[1][name(.)="a"]');

关于xpath查询第二部分的条件:

following-sibling::不仅针对第一个节点,而且针对之后的所有节点。因此,写following-sibling::a[1]会在文本后面返回第一个“a”节点,而不保证此节点会紧跟文本。

为确保后面的第一个节点是“a”标记,您需要在之后定位第一个节点并检查它是否为带有条件的“a”标记:

following-sibling::node()[1][name(.)="a"]