我需要一个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还是应该使用它?
答案 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"]