用xpathselect一个css类
我只想自己select一个叫做.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." "; }
我想写这个问题的规范答案,因为上面的答案有一个问题。
我们的问题
CSSselect器:
.foo
将select具有foo类的任何元素。
你如何在XPath中做到这一点?
尽pipeXPath比CSS强大,但XPath没有本地的CSS类select器 。 但是,有一个解决scheme。
正确的方式来做到这一点
XPath中的等效select器是:
//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
函数规范化空间带前后空白(也可以用一个空格replace空白字符序列)。
(从更一般的意义上说)这也是CSSselect器的等价物:
*[class~="foo"]
它将匹配任何其class属性值为空白分隔值列表的元素,其中一个元素恰好等于foo 。
几个明显的,但错误的方法来做到这一点
XPathselect器:
//*[@class="foo"]
不起作用! 因为它不会匹配具有多个类的元素,例如
<div class="foo bar">
如果类名周围有任何额外的空格,它也将不匹配:
<div class=" foo ">
“改进”的XPathselect器
//*[contains(@class, "foo")]
也不行! 因为它与foobar类错误地匹配元素
<div class="foobar">
值得一提的是这个家伙,他是我在网上发现的这个问题的最早发布的解决scheme: http : //dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes-在-xpathxslt /
//[@class="date"]
不是有效的xpath。
尝试//*[@class="date"]
,或者如果您知道它是一个图像, //img[@class="date"]
XPath 3.1引入了一个包含令牌的函数,从而最终解决了这个问题。 它旨在支持课程 。
例:
//*[contains-token(@class, "foo")]
这个function确保了空白(不仅仅是 (U + 0020))正确处理,在class级名称重复的情况下工作,一般覆盖边缘情况。
注意:截至今天(2016-12-13)XPath 3.1已经具有候选推荐的状态。
HTML允许不区分大小写的元素和属性名称,然后class是空格分隔的类名称列表。 在这里,我们去一个img
标签和名为date
的class
:
//*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]
另请参阅: CSSselect器到XPath的转换
注意模板中的减号标志! 如果您在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.
在XPath 2.0中,您可以:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
如Christian Weiske所述: https ://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm