Maison >développement back-end >tutoriel php >PHP DOM: Utilisation de XPATH
Points de base
query()
et evaluate()
. Bien que les deux effectuent des requêtes, la différence est que le type de résultat qu'ils renvoient, query()
renvoie DOMNodeList
, tandis que evaluate()
renvoie les résultats typés autant que possible. Cet article explorera XPath en profondeur, y compris ses fonctionnalités et comment il est implémenté en PHP. Vous constaterez que XPath peut réduire considérablement la quantité de code requise pour rédiger des requêtes et filtrer les données XML, et améliorer généralement les performances. Je vais démontrer la fonctionnalité PHP DOM XPATH en utilisant le même DTD et XML à partir du post précédent. Pour une revue rapide, voici à quoi ressemble DTD et XML:
<code class="language-xml"><!DOCTYPE library [ <!ELEMENT library (book*)> <!ELEMENT book (title, author, genre, chapter*)> <!ATTLIST book isbn ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT genre (#PCDATA)> <!ELEMENT chapter (chaptitle,text)> <!ATTLIST chapter position NMTOKEN #REQUIRED> <!ELEMENT chaptitle (#PCDATA)> <!ELEMENT text (#PCDATA)> ]></code>
<code class="language-xml"><?xml version="1.0" encoding="utf-8"?> <library> <book isbn="isbn1234"> <title>A Book</title> <author>An Author</author> <genre>Horror</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text></text> </chapter> </book> <book isbn="isbn1235"> <title>Another Book</title> <author>Another Author</author> <genre>Science Fiction</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text>Sit Dolor Amet...</text> </chapter> </book> </library></code>
requête de base xpath
xpath est une syntaxe pour interroger les documents XML. La forme la plus simple consiste à définir le chemin d'accès à l'élément auquel vous souhaitez accéder. En utilisant le document XML ci-dessus, la requête XPath suivante renvoie une collection de tous les éléments book
existants:
<code class="language-xpath">//library/book</code>
c'est tout. Deux barres obligées indiquent que library
sont les éléments racines du document, et une seule barre oblique indique que book
est ses éléments enfants. Très simple, n'est-ce pas? Mais que se passe-t-il si vous souhaitez spécifier un livre spécifique? Supposons que vous souhaitiez retourner n'importe quel livre écrit par "un auteur". Le xpath sera:
<code class="language-xpath">//library/book/author[text() = "An Author"]/..</code>
Vous pouvez utiliser text()
pour effectuer une comparaison sur la valeur d'un nœud entre crochets, et le suivant "/ .." signifie que nous voulons l'élément parent (c'est-à-dire déplacer un nœud vers le haut). La requête XPath peut être effectuée en utilisant l'une des deux fonctions: query()
et evaluate()
. Les deux effectuent des requêtes, mais la différence est le type de résultat qu'ils renvoient. query()
retournera toujours DOMNodeList
, et evaluate()
renvoie les résultats typés autant que possible. Par exemple, si votre requête XPath renvoie le nombre de livres écrits par un auteur particulier plutôt que le livre réel lui-même, alors query()
renverra un DOMNodeList
vide. evaluate()
retournera directement le numéro, vous pouvez donc l'utiliser immédiatement sans avoir à extraire des données du nœud.
Les avantages du code et de la vitesse de XPATH
faisons une démonstration rapide, renvoyant le nombre de livres écrits par un auteur spécifique. Nous allons d'abord examiner une approche viable, mais elle n'utilise pas XPATH. C'est pour vous montrer comment faire cela sans utiliser XPath et pourquoi XPath est si puissant.
<code class="language-xml"><!DOCTYPE library [ <!ELEMENT library (book*)> <!ELEMENT book (title, author, genre, chapter*)> <!ATTLIST book isbn ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT genre (#PCDATA)> <!ELEMENT chapter (chaptitle,text)> <!ATTLIST chapter position NMTOKEN #REQUIRED> <!ELEMENT chaptitle (#PCDATA)> <!ELEMENT text (#PCDATA)> ]></code>
La méthode suivante obtient le même résultat, mais utilise XPath pour sélectionner les livres écrits uniquement par un auteur spécifique:
<code class="language-xml"><?xml version="1.0" encoding="utf-8"?> <library> <book isbn="isbn1234"> <title>A Book</title> <author>An Author</author> <genre>Horror</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text></text> </chapter> </book> <book isbn="isbn1235"> <title>Another Book</title> <author>Another Author</author> <genre>Science Fiction</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text>Sit Dolor Amet...</text> </chapter> </book> </library></code>
Veuillez noter que nous avons éliminé la nécessité pour PHP de tester les valeurs des auteurs cette fois. Cependant, nous pouvons aller plus loin et utiliser la fonction XPATH count()
pour calculer le nombre d'occurrences de ce chemin.
<code class="language-xpath">//library/book</code>
Nous n'avons besoin que d'une seule ligne de XPATH pour récupérer les informations requises sans avoir besoin d'utiliser PHP pour effectuer un filtrage laborieux. En fait, c'est un moyen plus facile et plus concis d'écrire cette fonctionnalité! Notez que evaluate()
est utilisé dans le dernier exemple. En effet, la fonction count()
renvoie un résultat dactylographié. L'utilisation query()
retournera DOMNodeList
, mais vous constaterez qu'il s'agit d'une liste vide. Cela rend non seulement votre code plus concis, mais a également l'avantage de la vitesse. J'ai constaté que la version 1 a une vitesse moyenne de 30% plus rapide que la version 2, mais la version 3 est environ 10% plus rapide que la version 2 (environ 15% plus rapide que la version 1). Bien que ces mesures varient en fonction de votre serveur et de votre requête, l'utilisation de Pure XPath apporte souvent des avantages de vitesse considérables tout en rendant votre code plus facile à lire et à maintenir.
Fonction XPATH
xpath peut utiliser de nombreuses fonctions, et il existe de nombreuses ressources excellentes détaillant les fonctions disponibles. Si vous vous retrouvez à itérus sur DOMNodeLists
ou à comparer nodeValues
, vous pouvez trouver une fonction XPATH qui élimine beaucoup de code PHP. Vous avez vu l'utilisation de la fonction count()
. Utilisons la fonction id()
pour retourner le titre du livre avec l'ISBN donné. L'expression XPATH que vous devez utiliser est:
<code class="language-xpath">//library/book/author[text() = "An Author"]/..</code>
Notez que les valeurs à rechercher ici sont entourées de devis et séparées par des espaces;
<code class="language-php"><?php public function getNumberOfBooksByAuthor($author) { $total = 0; $elements = $this->domDocument->getElementsByTagName("author"); foreach ($elements as $element) { if ($element->nodeValue == $author) { $total++; } } return $total; // 修正:这里应该是 $total,而不是 $number } ?></code>
L'exécution des fonctions complexes dans XPATH est relativement simple; l'astuce consiste à connaître les fonctions disponibles.
en utilisant les fonctions PHP dans xpath
Parfois, vous pouvez avoir besoin de fonctionnalités plus puissantes que les fonctions XPath standard ne peuvent pas fournir. Heureusement, PHP Dom vous permet également d'intégrer les propres fonctions de PHP dans les requêtes XPath. Voyons retourner le nombre de mots dans le titre du livre. La fonction la plus simple, nous pouvons écrire la méthode comme ceci:
<code class="language-xml"><!DOCTYPE library [ <!ELEMENT library (book*)> <!ELEMENT book (title, author, genre, chapter*)> <!ATTLIST book isbn ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT genre (#PCDATA)> <!ELEMENT chapter (chaptitle,text)> <!ATTLIST chapter position NMTOKEN #REQUIRED> <!ELEMENT chaptitle (#PCDATA)> <!ELEMENT text (#PCDATA)> ]></code>
Cependant, nous pouvons également intégrer la fonction str_word_count()
directement dans la requête XPATH. Plusieurs étapes doivent être effectuées pour cela. Tout d'abord, nous devons enregistrer un espace de noms à l'aide de l'objet XPATH. La fonction PHP dans la requête XPath commence par "php:functionString
", suivie du nom de la fonction que vous souhaitez utiliser, enfermé entre parenthèses. De plus, l'espace de noms à définir est http://php.net/xpath
. L'espace de noms doit être défini à ce sujet; toute autre valeur provoquera une erreur. Ensuite, nous devons appeler registerPHPFunctions()
, qui indique à PHP que chaque fois que nous rencontrons une fonction avec "php:
" comme espace de noms, il doit être géré par PHP. La syntaxe réelle pour appeler une fonction est:
<code class="language-xml"><?xml version="1.0" encoding="utf-8"?> <library> <book isbn="isbn1234"> <title>A Book</title> <author>An Author</author> <genre>Horror</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text></text> </chapter> </book> <book isbn="isbn1235"> <title>Another Book</title> <author>Another Author</author> <genre>Science Fiction</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text>Sit Dolor Amet...</text> </chapter> </book> </library></code>
Mettez tout cela ensemble et obtenez la réimplémentation suivante de getNumberOfWords()
:
<code class="language-xpath">//library/book</code>
Notez que vous n'avez pas besoin d'appeler la fonction XPATH text()
pour fournir le texte du nœud. La méthode registerPHPFunctions()
le fera automatiquement. Cependant, ce qui suit est également valable:
<code class="language-xpath">//library/book/author[text() = "An Author"]/..</code>
Les fonctions PHP d'enregistrement ne sont pas limitées aux fonctions fournies avec PHP. Vous pouvez définir vos propres fonctions et les fournir dans XPath. La seule différence est que lorsque vous définissez une fonction, vous utilisez "php:function
" au lieu de "php:functionString
". De plus, seule la fonction elle-même ou des méthodes statiques peut être fournie. L'appel des méthodes d'instance n'est pas pris en charge. Voyons la fonctionnalité de base à l'aide d'une fonction régulière qui dépasse le cadre de la classe. La fonction que nous utiliserons ne retournera que les livres de "George Orwell". Pour chaque nœud que vous souhaitez inclure dans la requête, il doit retourner true
.
<code class="language-php"><?php public function getNumberOfBooksByAuthor($author) { $total = 0; $elements = $this->domDocument->getElementsByTagName("author"); foreach ($elements as $element) { if ($element->nodeValue == $author) { $total++; } } return $total; // 修正:这里应该是 $total,而不是 $number } ?></code>
L'argument transmis à la fonction est un tableau de DOMElements
. La fonction est responsable de l'itération sur le tableau et de la détermination de si le nœud à tester doit être renvoyé dans DOMNodeList
. Dans cet exemple, le nœud à tester est /book
, que nous utilisons /author
pour déterminer. Maintenant, nous pouvons créer la méthode getGeorgeOrwellBooks()
:
<code class="language-php"><?php public function getNumberOfBooksByAuthor($author) { $query = "//library/book/author[text() = '$author']/.."; $xpath = new DOMXPath($this->domDocument); $result = $xpath->query($query); return $result->length; } ?></code>
Si compare()
est une méthode statique, alors vous devez modifier la requête XPath pour lire:
<code class="language-php"><?php public function getNumberOfBooksByAuthor($author) { $query = "count(//library/book/author[text() = '$author']/..)"; $xpath = new DOMXPath($this->domDocument); return $xpath->evaluate($query); } ?></code>
En fait, toutes ces fonctionnalités peuvent être facilement écrites dans XPATH, mais cet exemple montre comment étendre une requête XPath pour la rendre plus complexe. La méthode d'objet ne peut pas être appelée dans XPATH. Si vous constatez que vous devez accéder à certaines propriétés ou méthodes d'objet pour compléter la requête XPath, la meilleure solution consiste à utiliser XPATH pour terminer la pièce que vous pouvez faire, puis utiliser toutes les méthodes ou attributs d'objets pour traiter le DOMNodeList
généré au besoin .
Résumé
xpath est un excellent moyen de réduire la quantité de code écrit et d'accélérer l'exécution du code lors du traitement des données XML. Bien que ne faisant pas partie de la spécification officielle DOM, les fonctionnalités supplémentaires fournies par PHP Dom vous permettent d'étendre les fonctions XPATH standard avec des fonctions personnalisées. Il s'agit d'une fonctionnalité très puissante, et à mesure que vous vous familiarisez avec la fonction XPATH, vous pouvez vous retrouver de moins en moins.
(image de Fotolia)
FAQS (FAQ) sur PHP DOM avec xpath
XPATH (Langue de chemin XML) est un langage de requête utilisé pour sélectionner les nœuds dans un document XML. Dans PHP DOM, XPATH est utilisé pour traverser les éléments et les propriétés dans un document XML. Il vous permet de trouver et de sélectionner des parties spécifiques d'un document XML de diverses manières, telles que la sélection d'un nœud par nom, la sélection d'un nœud par sa valeur d'attribut ou la sélection d'un nœud par son emplacement dans le document. Cela en fait un outil puissant pour analyser et manipuler les données XML dans PHP.
Pour créer une instance de Domxpath, vous devez d'abord créer une instance de la classe DomDocument. Une fois que vous avez obtenu l'objet DomDocument, vous pouvez créer un nouvel objet DOMXPATH en passant l'objet DomDocument au constructeur DOMXPATH. Voici un exemple:
<code class="language-xml"><!DOCTYPE library [ <!ELEMENT library (book*)> <!ELEMENT book (title, author, genre, chapter*)> <!ATTLIST book isbn ID #REQUIRED> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT genre (#PCDATA)> <!ELEMENT chapter (chaptitle,text)> <!ATTLIST chapter position NMTOKEN #REQUIRED> <!ELEMENT chaptitle (#PCDATA)> <!ELEMENT text (#PCDATA)> ]></code>
Vous pouvez sélectionner les nœuds à l'aide de la méthode query()
de l'objet Domxpath. La méthode query()
prend l'expression XPATH en tant que paramètre et renvoie un objet DomNodelist contenant tous les nœuds correspondant à l'expression. Par exemple:
<code class="language-xml"><?xml version="1.0" encoding="utf-8"?> <library> <book isbn="isbn1234"> <title>A Book</title> <author>An Author</author> <genre>Horror</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text></text> </chapter> </book> <book isbn="isbn1235"> <title>Another Book</title> <author>Another Author</author> <genre>Science Fiction</genre> <chapter position="first"> <chaptitle>chapter one</chaptitle> <text>Sit Dolor Amet...</text> </chapter> </book> </library></code>
Cela sélectionnera tous les éléments <book></book>
qui sont des éléments enfants de l'élément <title></title>
.
query()
dans evaluate()
DOMXPATH? query()
et evaluate()
sont utilisées pour évaluer les expressions XPATH. La différence est le type de résultat qu'ils renvoient. La méthode query()
renvoie le domnodéliste de tous les nœuds qui correspondent à l'expression XPATH. D'un autre côté, evaluate()
renvoie un résultat dactylographié, comme un booléen, un nombre ou une chaîne, selon l'expression XPATH. Si le résultat d'expression est un ensemble de nœuds, evaluate()
renvoie un domnodeliste.
Pour gérer les espaces de noms dans la requête XPath, vous devez enregistrer l'espace de noms avec l'objet Domxpath à l'aide de la méthode registerNamespace()
. Cette méthode a deux paramètres: le préfixe et l'espace de noms URI. Après avoir enregistré l'espace de noms, vous pouvez utiliser des préfixes dans votre requête XPath. Par exemple:
<code class="language-xpath">//library/book</code>
Vous pouvez utiliser le symbole @
suivi du nom de la propriété pour sélectionner les propriétés dans XPATH. Par exemple, pour sélectionner toutes les propriétés <a></a>
de l'élément href
, vous pouvez utiliser l'expression XPATH suivante: //a/@href
.
XPATH fournit de nombreuses fonctions qui peuvent être utilisées dans les expressions XPath. Ces fonctions peuvent être utilisées pour manipuler des chaînes, des nombres, des ensembles de nœuds, etc. Pour utiliser la fonction XPATH dans PHP DOM, incluez simplement la fonction dans l'expression XPATH. Par exemple, pour sélectionner tous les éléments <book></book>
avec un élément de prix d'une valeur supérieure à 30, vous pouvez utiliser la fonction number()
comme indiqué ci-dessous: //book[number(price) > 30]
.
Oui, vous pouvez utiliser XPATH avec des documents HTML dans PHP DOM. Cependant, comme le HTML n'est pas toujours bien formé XML, vous pouvez avoir des problèmes à essayer d'utiliser XPATH avec HTML. Pour éviter ces problèmes, vous pouvez utiliser la méthode loadHTML()
de la classe DomDocument pour charger le document HTML. Cette méthode analyse le HTML et corrige toutes les erreurs de formatage, vous permettant d'utiliser XPath avec l'objet DomDocument généré.
Lorsque vous utilisez XPATH dans PHP DOM, des erreurs peuvent se produire pour un certain nombre de raisons, telles qu'un format d'expression XPATH erroné ou un document XML ne peut pas être chargé. Pour gérer ces erreurs, vous pouvez permettre la gestion des erreurs de l'utilisateur à l'aide de la fonction libxml_use_internal_errors()
. Cette fonction entraînera le stockage des erreurs LiBXML en interne, vous permettant de les traiter dans votre code. Vous pouvez ensuite utiliser la fonction libxml_get_errors()
pour récupérer les erreurs et les traiter selon les besoins.
Bien que XPath lui-même ne fournit pas de moyen de modifier les documents XML, vous pouvez utiliser XPATH avec l'API DOM pour modifier les documents XML. Vous pouvez utiliser XPath pour sélectionner le nœud que vous souhaitez modifier, puis utiliser les méthodes fournies par l'API DOM pour modifier. Par exemple, vous pouvez utiliser la méthode removeChild()
de la classe DomNode pour supprimer un nœud, ou utiliser la méthode setAttribute()
de la classe Domement pour modifier la valeur de l'attribut.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!