Chcę wybrać tylko własną klasę o nazwie .date
Z jakiegoś powodu nie mogę tego uruchomić. Jeśli ktoś wie, co jest nie tak z moim kodem, będzie to bardzo cenne.
@$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')
Odpowiedzi:
Chcę napisać kanoniczną odpowiedź na to pytanie, ponieważ powyższa odpowiedź ma problem.
Nasz problem
CSS selektor:
.foo
wybierze dowolny element, który ma klasę foo .
Jak to robisz w XPath?
Chociaż XPath jest potężniejszy niż CSS, XPath nie ma natywnego odpowiednika selektora klas CSS . Jest jednak rozwiązanie.
Właściwy sposób, aby to zrobić
Odpowiedni selektor w XPath to:
//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
Funkcja normalize-space usuwa początkowe i końcowe białe znaki (a także zastępuje sekwencje białych znaków pojedynczą spacją).
(W bardziej ogólnym sensie) jest to również odpowiednik selektora CSS:
*[class~="foo"]
który będzie pasował do każdego elementu, którego wartością atrybutu klasy jest lista wartości oddzielonych białymi znakami, z których jedna jest dokładnie równa foo .
Kilka oczywistych, ale złych sposobów na zrobienie tego
Selektor XPath:
//*[@class="foo"]
nie działa! ponieważ na przykład nie będzie pasował do elementu, który ma więcej niż jedną klasę
<div class="foo bar">
Nie będzie również pasować, jeśli wokół nazwy klasy znajduje się dodatkowa spacja:
<div class=" foo ">
„Ulepszony” selektor XPath
//*[contains(@class, "foo")]
też nie działa! ponieważ na przykład błędnie dopasowuje elementy z klasą foobar
<div class="foobar">
Podziękowania dla tego gościa, który był najwcześniej opublikowanym rozwiązaniem tego problemu, jakie znalazłem w sieci: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space-seprated-attributes- in-xpathxslt /
źródło
<div class="foo\tbar">
? Mam na myśli nazwy klas oddzielone tabulatorem.//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
?//[@class="date"]
nie jest prawidłową ścieżką xpath.Spróbuj
//*[@class="date"]
, a jeśli wiesz, że to obraz,//img[@class="date"]
źródło
XPath 3.1 wprowadza funkcję zawierającą token i tym samym ostatecznie rozwiązuje ten problem „oficjalnie”. Jest przeznaczony do obsługi zajęć .
Przykład:
//*[contains-token(@class, "foo")]
Ta funkcja zapewnia
prawidłową obsługę białych znaków (nie tylko (U + 0020)), działa w przypadku powtarzania się nazw klas i generalnie obejmuje skrajne przypadki.
Uwaga: na dzień dzisiejszy (13.12.2016) XPath 3.1 ma status rekomendacji dla kandydatów .
źródło
W XPath 2.0 możesz:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
jak stwierdził Christian Weiske w: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
źródło
HTML zezwala na rozróżnianie wielkości liter w nazwach elementów i atrybutów, a klasa jest listą nazw klas oddzielonych spacjami. Tutaj idziemy do
img
tagu iclass
nazwanegodate
://*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]
Zobacz także: Selektor CSS do konwersji XPath
źródło
UWAŻAJ NA ZNAKI MINUS W WZORNIKU !!! Jeśli pytasz o „my-ownclass” w 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.
źródło