php 使用 xpath 选择一个 css 类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8808921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Selecting a css class with xpath
提问by Teddy13
I want to select just a class on its own called .date
我只想选择一个名为 .date 的类
For some reason, I cannot get this to work. If anyone knows what is wrong with my code, it would be much appreciated.
出于某种原因,我无法让它发挥作用。如果有人知道我的代码有什么问题,将不胜感激。
@$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." ";
}
回答by user716736
I want to write the canonical answer to this question because the answer above has a problem.
我想写这个问题的规范答案,因为上面的答案有问题。
Our problem
我们的问题
The CSSselector:
该CSS选择器:
.foo
will select any element that has the class foo.
将选择具有类foo 的任何元素。
How do you do this in XPath?
你如何在 XPath 中做到这一点?
Although XPath is more powerful than CSS, XPath doesn't have a native equivalent of a CSS class selector. However, there is a solution.
尽管 XPath 比 CSS 更强大,但XPath 没有原生的 CSS 类选择器。但是,有一个解决方案。
The right way to do it
正确的做法
The equivalent selector in XPathis:
XPath 中的等效选择器是:
//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
The function normalize-spacestrips leading and trailing whitespace (and also replaces sequences of whitespace characters by a single space).
函数normalize-space去除前导和尾随空格(并且还用单个空格替换空格字符序列)。
(In a more general sense) this is also the equivalent of the CSS selector:
(在更一般的意义上)这也相当于 CSS 选择器:
*[class~="foo"]
which will match any element whose classattribute value is a list of whitespace-separated values, one of which is exactly equal to foo.
这将匹配其类属性值为以空格分隔的值列表的任何元素,其中一个值完全等于foo。
A couple of obvious, but wrong ways to do it
一些明显但错误的方法
The XPath selector:
XPath 选择器:
//*[@class="foo"]
doesn't work! because it won't match an element that has more than one class, for example
不起作用!因为它不会匹配具有多个类的元素,例如
<div class="foo bar">
It also won't match if there is any extra whitespace around the class name:
如果类名周围有任何额外的空格,它也不会匹配:
<div class=" foo ">
The 'improved' XPath selector
“改进的”XPath 选择器
//*[contains(@class, "foo")]
doesn't work either! because it wrongly matches elements with the class foobar, for example
也不行!因为它错误地将元素与类foobar匹配,例如
<div class="foobar">
Credit goes to this fella, who was the earliest published solution to this problem that I found on the web: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes-in-xpathxslt/
归功于这个家伙,他是我在网上找到的最早发布的解决这个问题的方法:http: //dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes-在-xpathxslt/
回答by MrGlass
//[@class="date"]
is not a valid xpath.
//[@class="date"]
不是有效的 xpath。
Try //*[@class="date"]
, or if you know it is an image, //img[@class="date"]
试试//*[@class="date"]
,或者如果你知道它是一个图像,//img[@class="date"]
回答by Robin Pokorny
XPath 3.1introduces a function contains-tokenand thus finally solves this ‘officially'. It is designed to support classes.
XPath 3.1引入了一个函数contains-token,从而最终“正式”解决了这个问题。它旨在支持类。
Example:
例子:
//*[contains-token(@class, "foo")]
//*[contains-token(@class, "foo")]
This function makes sure that white space (not only (U+0020)) is handled correctly, works in case of class name repetition, and generally covers the edge cases.
此函数确保正确处理空格(不仅是(U+0020)),在类名重复的情况下工作,并且通常涵盖边缘情况。
Note:As of today (2016-12-13) XPath 3.1 has status of Candidate Recommendation.
注意:截至今天 (2016-12-13) XPath 3.1 的状态为Candidate Recommendation。
回答by Memke
In XPath 2.0 you can:
在 XPath 2.0 中,您可以:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
as stated by Christian Weiske in: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
正如 Christian Weiske 所述:https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
回答by hakre
HTML allows case-insensitive element and attribute names and then class is a space separated list of class-names. Here we go for a img
tag and the class
named date
:
HTML 允许不区分大小写的元素和属性名称,然后 class 是一个以空格分隔的类名称列表。在这里,我们寻找一个img
标签和class
命名的date
:
//*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]
See as well: CSS Selector to XPath conversion
另请参阅:CSS 选择器到 XPath 的转换
回答by Vlado
BEWARE OF MINUS SIGNS IN TEMPLATE !!! If you are querying for "my-ownclass" in DOM:
当心模板中的减号!!!如果您在 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.