Я хочу выбрать только класс с именем .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." ";
}
contains(@class, 'date')
Ответы:
Я хочу написать канонический ответ на этот вопрос, потому что в приведенном выше ответе есть проблема.
Наша проблема
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 /
источник
<div class="foo\tbar">
? Я имею в виду, имена классов разделены табуляцией.//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
?//[@class="date"]
не является допустимым xpath.Попробуйте
//*[@class="date"]
, или, если вы знаете, что это изображение,//img[@class="date"]
источник
XPath 3.1 вводит функцию contains-token и, таким образом, наконец решает эту проблему «официально». Он предназначен для поддержки классов .
Пример:
//*[contains-token(@class, "foo")]
Эта функция гарантирует, что пробелы (не только
(U + 0020)) обрабатываются правильно, работают в случае повторения имени класса и, как правило, покрывают крайние случаи.
Примечание. На сегодняшний день (13.12.2016) XPath 3.1 имеет статус кандидата в рекомендации .
источник
В XPath 2.0 вы можете:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
как указано Кристианом Вайске в: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
источник
HTML допускает регистронезависимые имена элементов и атрибутов, а затем класс представляет собой список имен классов, разделенных пробелами. Здесь мы идем за
img
тегом иclass
именуемымdate
://*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]
Смотрите также: CSS Selector to XPath преобразование
источник
ОСТОРОЖНО ЗНАКОВ МИНУС В ШАБЛОНЕ !!! Если вы запрашиваете "мой собственный класс" в DOM:
<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.
источник