web-dev-qa-db-fra.com

Comment parcourir les éléments DOM en PHP?

J'ai un fichier XML chargé dans un document DOM, je souhaite parcourir toutes les balises "foo", en obtenant des valeurs pour toutes les balises situées en dessous. Je sais que je peux obtenir des valeurs via

$element = $dom->getElementsByTagName('foo')->item(0);
foreach($element->childNodes as $node){
    $data[$node->nodeName] = $node->nodeValue;
}

Cependant, ce que j'essaie de faire, c'est à partir d'un XML comme:

<stuff>
  <foo>
    <bar></bar>
      <value/>
    <pub></pub>
  </foo>
  <foo>
    <bar></bar>
    <pub></pub>
  </foo>
  <foo>
    <bar></bar>
    <pub></pub>
  </foo>
  </stuff>

parcourez chaque balise foo, et obtenez bar ou pub, et obtenez des valeurs à partir de là. Maintenant, comment puis-je parcourir foo pour pouvoir toujours accéder à des nœuds enfants spécifiques par leur nom?

29
Esa

Non testé, mais qu'en est-il:

$elements = $dom->getElementsByTagName('foo');
$data = array();
foreach($elements as $node){
    foreach($node->childNodes as $child) {
        $data[] = array($child->nodeName => $child->nodeValue);
    }
}
42
roryf

Il est généralement préférable d'utiliser XPath pour interroger un document que pour écrire du code dépendant de la connaissance de la structure du document. Il y a deux raisons. Premièrement, il y a beaucoup moins de code à tester et à déboguer. Deuxièmement, si la structure du document change, il est beaucoup plus facile de modifier une requête XPath que de modifier un tas de code.

Bien sûr, vous devez apprendre XPath, mais (la plupart des) XPath n’est pas sorcier.

Le DOM de PHP utilise la méthode xpath_eval pour effectuer des requêtes XPath. C'est documenté ici , et les notes de l'utilisateur incluent de très bons exemples.

4
Robert Rossney

Voici une autre façon (paresseuse) de le faire.

$data[][$node->nodeName] = $node->nodeValue;
1

Avec FluidXML vous pouvez interroger et itérer XML très facilement.

$data = [];

$store_child = function($i, $fooChild) use (&$data) {
    $data[] = [ $fooChild->nodeName => $fooChild->nodeValue ];
};

fluidxml($dom)->query('//foo/*')->each($store_child);

https://github.com/servo-php/fluidxml

0
Daniele Orlando