Je souhaite sélectionner uniquement une classe appelée .date
Pour une raison quelconque, je ne peux pas faire fonctionner cela. 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." ";
}
contains(@class, 'date')
Réponses:
Je veux écrire la réponse canonique à cette question car la réponse ci-dessus a un problème.
Notre problème
Le sélecteur CSS :
sélectionnera tout é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.
La bonne façon de le faire
Le sélecteur équivalent dans XPath est:
La fonction normalize-space supprime les espaces de début et de fin (et remplace également les séquences de caractères d'espaces par un seul espace).
(Dans un sens plus général) c'est aussi l'équivalent du sélecteur CSS:
qui correspondra à tout élément dont la valeur d'attribut de classe est une liste de valeurs séparées par des espaces, dont l'une est exactement égale à foo .
Quelques façons évidentes mais incorrectes de le faire
Le sélecteur XPath:
ne fonctionne pas! car il ne correspondra pas à un élément qui a plus d'une classe, par exemple
Il ne correspondra pas non plus s'il y a un espace supplémentaire autour du nom de la classe:
Le sélecteur XPath `` amélioré ''
ne fonctionne pas non plus! car il correspond à tort des éléments avec la classe foobar , par exemple
Le mérite revient à ce type, 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-attributes- in-xpathxslt /
la source
<div class="foo\tbar">
? Je veux dire, les noms de classe séparés par une tabulation.//*[contains(concat(" ", normalize-space(@class), " "), " foo ")]
?//[@class="date"]
n'est pas un xpath valide.Essayez
//*[@class="date"]
, ou si vous savez que c'est une image,//img[@class="date"]
la source
XPath 3.1 introduit une fonction contains-token et résout ainsi finalement cela «officiellement». Il est conçu pour prendre en charge les classes .
Exemple:
//*[contains-token(@class, "foo")]
Cette fonction s'assure que l'espace blanc (pas seulement
(U + 0020)) est géré correctement, fonctionne en cas de répétition du nom de classe et couvre généralement les cas de bord.
Remarque: À partir d'aujourd'hui (13/12/2016) XPath 3.1 a le statut de recommandation candidate .
la source
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
la source
HTML autorise les noms d'éléments et d'attributs insensibles à la casse, puis la classe est une liste de noms de classe séparés par des espaces. Ici, nous allons pour une
img
balise et leclass
nommédate
:Voir aussi: Conversion du sélecteur CSS en XPath
la source
Méfiez-vous des signes moins dans le modèle !!! Si vous recherchez "ma-propre classe" dans DOM:
la source