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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:33:24  来源:igfitidea点击:

Selecting a css class with xpath

phphtmlxmlxpathweb

提问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

也不行!因为它错误地将元素与类foob​​ar匹配,例如

<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 imgtag and the classnamed 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.