Je veux juste choisir une classe appelée .date
Pour une raison quelconque, je ne peux pas que cela fonctionne. Si quelqu'un sait ce qui ne va pas avec mon code, ce serait très apprécié.
@$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." ";
}
Je veux écrire la réponse canonique à cette question parce que la réponse ci-dessus a un problème.
Le sélecteur [~ # ~] css [~ # ~] :
.foo
sélectionnera n'importe quel élément ayant la classe foo .
Comment faites-vous cela dans XPath?
Bien que XPath soit plus puissant que CSS, XPath n’a pas d’équivalent natif d’un sélecteur de classe CSS . Cependant, il existe une solution.
Le sélecteur équivalent dans XPath est:
//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
La fonction normaliser-espace supprime les espaces de début et de fin (et remplace également les séquences de caractères d'espacement par un seul espace).
(Dans un sens plus général), c'est aussi l'équivalent du sélecteur CSS:
*[class~="foo"]
qui correspond à tout élément dont la valeur d'attribut class class est une liste de valeurs séparées par des espaces, dont l'une est exactement égale à foo .
Le sélecteur XPath:
//*[@class="foo"]
ne fonctionne pas! parce qu'il ne correspondra pas à un élément ayant plus d'une classe, par exemple
<div class="foo bar">
Cela ne correspondra pas non plus s'il y a un espace supplémentaire autour du nom de la classe:
<div class=" foo ">
Le sélecteur XPath 'amélioré'
//*[contains(@class, "foo")]
ne fonctionne pas non plus! car il associe à tort des éléments à la classe foobar , par exemple
<div class="foobar">
Le mérite en revient à cet homme, qui était la première solution publiée à ce problème que j'ai trouvée sur le Web: http://dubinko.info/blog/2007/10/01/simple-parsing-of-space- seprated-attributs-in-xpathxslt /
//[@class="date"]
n'est pas un xpath valide.
Essayez //*[@class="date"]
, ou si vous savez que c'est une image, //img[@class="date"]
XPath 3.1 introduit une fonction contient-jeton et résout donc finalement ce "officiellement". Il est conçu pour classes de support .
Exemple:
//*[contains-token(@class, "foo")]
Cette fonction garantit que l’espace blanc (pas seulement (U + 0020)) est gérée correctement, fonctionne en cas de répétition du nom de classe et couvre généralement les cas Edge.
Remarque: À compter d'aujourd'hui (2016-12-13), l'état de XPath 3.1 est Recommandation du candidat.
Dans XPath 2.0, vous pouvez:
//*[count(index-of(tokenize(@class, '\s+' ), 'foo')) = 1]
comme indiqué par Christian Weiske dans: https://cweiske.de/tagebuch/XPath%3A%20Select%20element%20by%20class.htm
Le HTML autorise les noms d’attributs et d’éléments insensibles à la casse, puis class est une liste de noms de classes séparée par des espaces. Ici nous allons pour une balise img
et le class
nommé date
:
//*['IMG' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')]/@*['CLASS' = translate(name(.), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') and contains(concat(' ', normalize-space(.), ' '), concat(' ', 'date', ' '))]
Voir aussi: Conversion du sélecteur CSS en XPath
ATTENTION AUX SIGNES MOINS DANS LE MODÈLE !!! Si vous recherchez "my-ownclass" dans 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.