web-dev-qa-db-ja.com

xpathを使用してcssクラスを選択する

.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." ";
}
78
Teddy13

上記の答えには問題があるので、この質問に対する標準的な答えを書きたいと思います。

私たちの問題

[〜#〜] css [〜#〜]セレクター:

.foo

クラスfooを持つ要素を選択します。

XPathでこれをどのように行いますか?

XPathはCSSよりも強力ですが、XPathにはCSSクラスセレクターと同等のネイティブ機能がありません。ただし、解決策があります。

それを行う正しい方法

XPathの同等のセレクタは次のとおりです。

//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]

関数 normalize-space は、先頭と末尾の空白を削除します(また、空白文字のシーケンスを単一のスペースに置き換えます)。

(より一般的な意味では)これはCSSセレクターと同等です:

*[class~="foo"]

これは、class属性値が空白で区切られた値のリストであり、そのうちの1つが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 /

229
user716736

//[@class="date"]は有効なxpathではありません。

//*[@class="date"]、または画像であることがわかっている場合は、//img[@class="date"]

10
MrGlass

XPath 3.1は関数 contains-token を導入し、最終的にこれを「公式に」解決します。 クラスをサポート に設計されています。

例:

//*[contains-token(@class, "foo")]

この関数は、空白((U + 0020)だけでなく)が正しく処理されるようにし、クラス名の繰り返しの場合に機能し、通常Edgeのケースをカバーします。


注:今日(2016-12-13)XPath 3.1のステータスは勧告候補です。

7
Robin Pokorny

XPath 2.0では次のことができます。

//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]

christian Weiskeが次のように述べています: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm

3
Memke

HTMLでは、大文字と小文字を区別しない要素名と属性名を使用できます。クラスは、スペースで区切られたクラス名のリストです。ここでは、imgタグとclassという名前のdateを探します。

//*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]

参照: CSSセレクターからXPathへの変換

1
hakre

テンプレートのマイナス記号に注意してください!!! 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.
1
Vlado