Xpath 查询不匹配



我有以下代码:

$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

最新更新