J'utilise PHP DOM et j'essaie d'obtenir un élément dans un nœud DOM qui a un nom de classe donné. Quelle est la meilleure façon d'obtenir ce sous-élément?
Mise à jour: J'ai fini par utiliser Mechanize
pour PHP qui était beaucoup plus facile à travailler.
Réponses:
Mise à jour: version Xpath du
*[@class~='my-class']
sélecteur cssDonc, après mon commentaire ci-dessous en réponse au commentaire de hakre, je suis devenu curieux et j'ai regardé le code derrière
Zend_Dom_Query
. Il semble que le sélecteur ci-dessus soit compilé sur le chemin xpath suivant (non testé):[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]
donc le php serait:
Fondamentalement, tout ce que nous faisons ici est de normaliser l'
class
attribut afin que même une seule classe soit délimitée par des espaces et que la liste complète des classes soit délimitée par des espaces. Ajoutez ensuite la classe que nous recherchons avec un espace. De cette façon, nous recherchons et trouvons uniquement des instances demy-class
.Utiliser un sélecteur xpath?
S'il ne s'agit que d'un seul type d'élément, vous pouvez remplacer le
*
par la variable particulière.Si vous avez besoin d'en faire beaucoup avec un sélecteur très complexe, je recommanderais celui
Zend_Dom_Query
qui prend en charge la syntaxe du sélecteur CSS (à la jQuery):la source
my-class2
aussi, mais assez douce. Un moyen de ne choisir que le premier de tous les éléments?class
peut avoir plus d'une classe par exemple:<a class="my-link link-button nav-item">
.//*[contains(concat(' ', normalize-space(@class), ' '), ' classname ')]
(très informatif: sélecteurs CSS et expressions XPath ).contains
en combinaison avecconcat
... nous discutons juste des détails du remplissage des espaces des deux côtés de la classe que vous recherchez ou ne rembourrez qu'un côté. Les deux devraient fonctionner cependant.Si vous souhaitez obtenir le code interne de la classe sans zend, vous pouvez utiliser ceci:
la source
$classname = 'main-article'
Je pense que la méthode acceptée est meilleure, mais je suppose que cela pourrait également fonctionner
la source
$classResult = getElementByClass($dom, 'div', 'm-signature-pad'); $classResult->nodeValue = ''; $enode = $dom->createElement('img'); $enode->setAttribute('src', $signatureImage); $classResult->appendChild($enode);
Il existe également une autre approche sans l'utilisation de
DomXPath
ouZend_Dom_Query
.Sur la base de la fonction originale de dav, j'ai écrit la fonction suivante qui renvoie tous les enfants du nœud parent dont la balise et la classe correspondent aux paramètres.
supposons que vous ayez une variable
$html
le HTML suivant:l'utilisation de
getElementsByClass
est aussi simple que:la source
DOMDocument est lent à taper et phpQuery a de graves problèmes de fuite de mémoire. J'ai fini par utiliser:
https://github.com/wasinger/htmlpagedom
Pour sélectionner une classe:
J'espère que cela aide aussi quelqu'un d'autre
la source