Introduction:
I want to loop through XML files with flexible categories structure.
Problem:
I don't know to loop through a theoretical infinte subcategories without having to make x amount of "for each" statements (See coding example in the bottom). How do I dynamically traverse the categories structure?
<?xml version="1.0" encoding="utf-8"?>
<catalog>
<category name="Category - level 1">
<category name="Category - level 2" />
<category name="Category - level 2">
<category name="Category - level 3" />
</category>
<category name="Category - level 2">
<category name="Category - level 3">
<category name="Category - level 4" />
</category>
</category>
</category>
</catalog>
What I have now:
I have no problem looping through XML files with a set structure:
<catalog>
<category name="Category - level 1">
<category name="Category - level 2">
<category name="Category - level 3" />
</category>
<category name="Category - level 2">
<category name="Category - level 3" />
</category>
</category>
</catalog>
Coding example:
//$xml holds the XML file
foreach ( $xml AS $category_level1 )
{
echo $category_level1['name'];
foreach ( $category_level1->category AS $category_level2 )
{
echo $category_level2['name'];
foreach ( $category_level2->category AS $category_level3 )
{
echo $category_level3['name'];
}
}
}
Getting the name attributes from your categories is likely fastest when done via XPath, e.g.
$categoryNames = $doc->xpath('//category/@name');
However, if you want to recursively iterate over an arbitrary nested XML structure, you can also use the SimpleXMLIterator, e.g. with $xml
being the string you gave:
$sxi = new RecursiveIteratorIterator(
new SimpleXMLIterator($xml),
RecursiveIteratorIterator::SELF_FIRST);
foreach($sxi as $node) {
echo str_repeat("\t", $sxi->getDepth()), // indenting
$node['name'], // getting attribute name
PHP_EOL; // line break
}
will give
Category - level 1
Category - level 2
Category - level 2
Category - level 3
Category - level 2
Category - level 3
Category - level 4
Like said in the beginning, when just wanting to get all name attributes, use XPath, because iterating over each and every node is slow. Use this approach only when you want to do more complex things with the nodes, for instance adding something to them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With