2008-10-10 7 views
28

Ich habe eine XML-Datei in ein DOM-Dokument geladen, Ich möchte alle 'foo' Tags durchlaufen, erhalten Werte von jedem Tag darunter. Ich weiß, dass ich Werte überWie durchläuft ich DOM-Elemente in PHP?

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

Allerdings bekommen können, was ich zu tun werde versuchen, aus einer XML ist wie,

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

Iterierte über jeden foo-Tag und erhalten spezifische bar oder pub, und erhalten Sie Werte von dort. Nun, wie kann ich über foo iterieren, so dass ich noch auf bestimmte Kindknoten nach Namen zugreifen kann?

Antwort

41

Nicht getestet, aber was ist:

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

Keine Notwendigkeit für $ element. Füge einfach $ data wie folgt an: $ data [] = array ($ child-> nodeName => $ child-> nodeValue); – troelskn

+1

Das hat den Trick gemacht! Ich dachte zu kompliziert. Muss müde sein. – Esa

+0

Aktualisiert den Code basierend auf Kommentar von troelskn, ist das was du meintest? – roryf

4

Es ist im Allgemeinen viel besser XPath zu verwenden, um ein Dokument zu fragen, als es, Code zu schreiben, die auf der Kenntnis der Struktur des Dokuments abhängt. Es gibt 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 einen Code zu ändern.

Natürlich müssen Sie XPath lernen, aber (die meisten) XPath ist kein Hexenwerk.

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

1

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

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

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