webentwicklung-frage-antwort-db.com.de

Wie durchlaufe ich DOM-Elemente in PHP?

Ich habe eine XML-Datei in ein DOM-Dokument geladen. Ich möchte alle "foo" -Tags durchlaufen und Werte von jedem Tag darunter abrufen. Ich weiß, dass ich über Werte erhalten kann

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

Was ich jedoch versuche zu tun, ist von einem XML wie,

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

iterieren Sie über jedes foo - Tag, und rufen Sie das spezifische bar oder pub ab. Rufen Sie von dort Werte ab. Wie kann ich nun über foo iterieren, damit ich weiterhin namentlich auf bestimmte untergeordnete Knoten zugreifen kann?

29
Esa

Nicht getestet, aber was ist mit:

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

Im Allgemeinen ist es viel besser, XPath zum Abfragen eines Dokuments zu verwenden als zum Schreiben von Code, der von der Kenntnis der Struktur des Dokuments abhängt. Dafür gibt es zwei Gründe. Erstens gibt es viel weniger Code zum Testen und Debuggen. Zweitens: Wenn sich die Struktur des Dokuments ändert, ist es viel einfacher, eine XPath-Abfrage zu ändern als eine Menge Code.

Natürlich müssen Sie XPath lernen, aber (der größte Teil) von XPath ist keine Hexerei.

Das DOM von PHP verwendet die xpath_eval-Methode, um XPath-Abfragen auszuführen. Es ist dokumentiert hier , und die Benutzerhinweise enthalten einige sehr gute Beispiele.

4
Robert Rossney

Hier ist ein anderer (fauler) Weg, es zu tun.

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

Mit FluidXML können Sie XML sehr einfach abfragen und iterieren.

$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