[英]Is there an easy way to get subelements with DomDocument and DomXPath?
假设我有这样的HTML:
<div id="container">
<li class="list">
Test text
</li>
</div>
我想得到li
的内容。
我可以使用以下代码获取容器div的内容:
$html = '
<div id="container">
<li class="list">
Test text
</li>
</div>';
$dom = new \DomDocument;
$dom->loadHTML($html);
$xpath = new \DomXPath($dom);
echo $dom->saveHTML($xpath->query("//div[@id='container']")->item(0));
我希望通过简单地将它添加到查询中来获取子元素的内容(就像你在simpleHtmlDom中可以做到的那样):
echo $dom->saveHTML($xpath->query("//div[@id='container'] li[@class='list']")->item(0));
但是一个警告(后面是一个致命的错误)被抛出,说:
Warning: DOMXPath::query(): Invalid expression ...
我知道要做我想要的唯一方法是:
$html = '
<div id="container">
<li class="list">
Test text
</li>
</div>';
$dom = new \DomDocument;
$dom->loadHTML($html);
$xpath = new \DomXPath($dom);
$dom2 = new \DomDocument;
$dom2->loadHTML(trim($dom->saveHTML($xpath->query("//div[@id='container']")->item(0))));
$xpath2 = new \DomXPath($dom2);
echo $xpath2->query("//li[@class='list']")->item(0)->nodeValue;
然而,这是为了获取li
的内容而进行的大量代码,问题在于项目嵌套得更深(如果我想得到`div#container ul.container li.list)我必须继续添加越来越多的代码。
使用simpleHtmlDom,我所要做的就是:
$html->find('div#container li.list', 0);
我错过了使用DomDocument和DomXPath做事的简单方法,还是真的很难?
你最初的尝试很接近; 你的语法只是一个角色。 尝试以下XPath:
//div[@id='container']/li[@class='list']
你可以看到div
节点和li
节点之间有一个空格,那里应该有正斜杠。
SimpleHTMLDOM使用CSS选择器,而不是Xpath。 CSS选择器中的任何内容也可以使用Xpath完成。 DOMXpath :: query()仅支持返回节点列表的Xpath表达式,但Xpath也可以返回标量。
在Xpath中, /
用于分隔位置路径的各个部分,而不是空格。 它还有两个含义。 A /
在位置路径的开头使其成为绝对路径(它从文档而不是当前上下文节点开始)。 第二个/
是后代轴的短语法。
尝试:
$html = '
<div id="container">
<li class="list">
Test text
</li>
</div>';
$dom = new \DomDocument;
$dom->loadHTML($html);
$xpath = new \DomXPath($dom);
echo trim($xpath->evaluate("string(//div[@id='container']//li[@class='list'])"));
输出:
Test text
在CSS选择器序列中,空间是两个选择器的组合子。
foo bar
//foo//bar
/descendant::foo/descendant::bar
另一个组合子将是>
为一个孩子。 此轴是Xpath中的默认轴。
foo > bar
//foo/bar
/descendant::foo/child::bar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.