Xpath 查询不匹配
Xpath query couldn't match
我有以下代码:
$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?我做错了什么?
您的代码正在引发一些警告:
Warning: DOMXPath::query(): Invalid expression in ... on line ...
一个好主意是在您的服务器中显示这些警告,为此,请参阅 。
因此,您的 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
我有以下代码:
$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?我做错了什么?
您的代码正在引发一些警告:
Warning: DOMXPath::query(): Invalid expression in ... on line ...
一个好主意是在您的服务器中显示这些警告,为此,请参阅 。
因此,您的 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