我想只选择一个名为.date
的类出于某种原因,我无法让它发挥作用。如果有人知道我的代码有什么问题,我们将不胜感激。
@$doc = new DOMDocument();
@$doc->loadHTML($html);
$xml = simplexml_import_dom($doc); // just to make xpath more simple
$images = $xml->xpath('//[@class="date"]');
foreach ($images as $img)
{
echo $img." ";
}
答案 0 :(得分:229)
我想写这个问题的规范答案,因为上面的答案有问题。
CSS 选择器:
.foo
将选择任何具有 foo 类的元素。
如何在XPath中执行此操作?
虽然XPath比CSS更强大,但是 XPath没有CSS类选择器的本机等价物。但是,有一个解决方案。
XPath 中的等效选择器是:
//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
函数normalize-space剥离前导和尾随空格(并且还用单个空格替换空白字符序列)。
(在更一般意义上)这也是CSS选择器的等价物:
*[class~="foo"]
将匹配任何类属性值是以空格分隔的值列表的元素,其中一个值与 foo 完全相同。
XPath选择器:
//*[@class="foo"]
不起作用!因为它不匹配具有多个类的元素,例如
<div class="foo bar">
如果类名周围有任何额外的空格,它也不会匹配:
<div class=" foo ">
'改进的'XPath选择器
//*[contains(@class, "foo")]
也不起作用!因为它错误地匹配了 foobar 类的元素,例如
<div class="foobar">
归功于这个家伙,他是我在网上发现的最早发布的解决方案: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes-in-xpathxslt/
答案 1 :(得分:9)
//[@class="date"]
不是有效的xpath。
尝试//*[@class="date"]
,或者如果你知道它是图片,//img[@class="date"]
答案 2 :(得分:7)
XPath 3.1 引入了一个函数contains-token,因此最终解决了这个“正式”问题。它的目的是support classes。
示例:强>
//*[contains-token(@class, "foo")]
此函数可确保正确处理空格(不仅(U + 0020)),在类名重复的情况下有效,并且通常涵盖边缘情况。
注意:截至今日(2016-12-13),XPath 3.1的状态为候选推荐。
答案 3 :(得分:3)
在XPath 2.0中,您可以:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
如Christian Weiske所述: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
答案 4 :(得分:1)
HTML允许不区分大小写的元素和属性名称,然后class是一个以空格分隔的类名列表。我们在这里找到img
代码和名为class
的{{1}}:
date
答案 5 :(得分:1)
在模板中注意减号!如果您在DOM中查询“my-ownclass”:
<ul class="my-ownclass"><li>...</li></ul>
<ul class="someother"><li>...</li></ul>
<ul><li>...</li></ul>
$finder = new DomXPath($dom);
$nodes = $finder->query(".//ul[contains(@class, 'my-ownclass')]"); // This will NOT behave as expected! This will strangely match all the <ul> elements in DOM.
$nodes = $finder->query(".//ul[contains(@class, 'ownclass')]"); // This will match the element.