Home » Php » How do I iterate through DOM elements in PHP?

How do I iterate through DOM elements in PHP?

Posted by: admin November 30, 2017 Leave a comment

Questions:

I have an XML file loaded into a DOM document,
I wish to iterate through all ‘foo’ tags, getting values from every tag below it. I know I can get values via

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

However, what I’m trying to do, is from an XML like,

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

iterate over every foo tag, and get specific bar or pub, and get values from there.
Now, how do I iterate over foo so that I can still access specific child nodes by name?

Answers:

Not tested, but what about:

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

Questions:
Answers:

It’s generally much better to use XPath to query a document than it is to write code that depends on knowledge of the document’s structure. There are two reasons. First, there’s a lot less code to test and debug. Second, if the document’s structure changes it’s a lot easier to change an XPath query than it is to change a bunch of code.

Of course, you have to learn XPath, but (most of) XPath isn’t rocket science.

PHP’s DOM uses the xpath_eval method to perform XPath queries. It’s documented here, and the user notes include some pretty good examples.

Questions:
Answers:

Here’s another (lazy) way to do it.

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

Questions:
Answers:

With FluidXML you can query and iterate XML very easly.

$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