我有以下代码:
$content = 'whatever <iframe style="display:none;" src="https://www.example.com/hello/id"></iframe>';
$dom = new DOMDocument();
$dom->loadHTML($content);
$xp = new DOMXpath($dom);
$nodes = $xp->query("iframe[src*='.example.com/hello/']");
foreach($nodes as $node){
echo $node->nodeName ." : ". $node->nodeValue, PHP_EOL;
}
谁能告诉我为什么Xpath查询不能匹配iframe?我做错了什么?
您的代码正在引发一些警告:
警告:DOMXPath::query(): Invalid expression in…在线…
一个好主意是在您的服务器中显示这些警告,为此,请参阅https://stackoverflow.com/a/21429652/2123530。
所以,您的XPath查询是无效的,这来自于您试图搜索属性src
以包含字符串的方式。
构建你的使用有一个CSS构造,不是一个XPath。
在XPath中等价的是
iframe[contains(@src, '.example.com/hello/')]
但是,您还没有完成,因为,当您将HTML节点的随机部分提供给DOMDocument
时,它将尝试使其成为有效的HTML文档,因此执行如下操作:
<?php
$content = 'whatever <iframe style="display:none;" src="https://www.example.com/hello/id"></iframe>';
$dom = new DOMDocument();
$dom->loadHTML($content);
$dom->formatOutput = true;
echo $dom->saveXML();
将使您意识到您的HTML代码-来自$content
的代码-变成了
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<body>
<p>whatever <iframe style="display:none;" src="https://www.example.com/hello/id"/></p>
</body>
</html>
从这里开始,你有三个解决方案:
- 在整个HTML文档中查找任何匹配的
iframe
//iframe[contains(@src,'.example.com/hello/')]
- 或者你指向它的特定级别
html > body > p > iframe
/html/body/p/iframe[contains(@src,'.example.com/hello/')]
- 您可以使用通配符指向父节点的特定级别
/*/*/*/iframe[contains(@src,'.example.com/hello/')]
一起
<?php
$content = 'whatever <iframe style="display:none;" src="https://www.example.com/hello/id"></iframe>';
$dom = new DOMDocument();
$dom->loadHTML($content);
$xp = new DOMXpath($dom);
echo $xp->query("//iframe[contains(@src,'.example.com/hello/')]")
->item(0)
->nodeName,
PHP_EOL,
$xp->query("/html/body/p/iframe[contains(@src,'.example.com/hello/')]")
->item(0)
->nodeName,
PHP_EOL,
$xp->query("/*/*/*/iframe[contains(@src,'.example.com/hello/')]")
->item(0)
->nodeName;
给:
iframe
iframe
iframe