web-dev-qa-db-ja.com

PHPでDOM要素を反復処理する方法を教えてください。

XMLファイルをDOMドキュメントにロードしました。すべての「foo」タグを反復処理し、その下のすべてのタグから値を取得します。私は値を取得できることを知っています

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

しかし、私がやろうとしていることは、XMLのようなものです、

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

すべてのfooタグを反復処理して、特定のbarまたはpubを取得し、そこから値を取得します。では、fooを反復処理して、特定の子ノードに名前でアクセスできるようにするにはどうすればよいですか?

31
Esa

テストされていませんが、以下についてはどうですか:

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

一般に、ドキュメントのクエリにはXPathを使用する方が、ドキュメントの構造に関する知識に依存するコードを記述するよりもはるかに優れています。理由は2つあります。まず、テストおよびデバッグするコードが大幅に少なくなります。次に、ドキュメントの構造が変更された場合は、一連のコードを変更するよりも、XPathクエリを変更する方がはるかに簡単です。

もちろん、XPathを学ぶ必要がありますが、XPath(の大部分)はロケット科学ではありません。

PHPのDOMはxpath_evalメソッドを使用して、XPathクエリを実行します。それは here で文書化されており、ユーザーノートにはかなり良い例がいくつか含まれています。

4
Robert Rossney

FluidXML を使用すると、非常に簡単にXMLをクエリおよび反復できます。

$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