PHP: using simplexml to cycle through all levels of an XML file

I have a function that uses simplexml to return the first level of nodes to an XML file and writes it to an unordered list:

function printAssetMap() { $xml = simplexml_load_file(X_ASSETS); $assets = $xml->asset; $html = '<ul>'."\n"; foreach ($assets as $asset) { $html .= '<li id="asset'.$asset->asset_assetid.'"><ins>&nbsp;</ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a></li>'."\n"; }//end foreach $html .= '</ul>'."\n"; return $html; }// printAssetMap() 

The XML I use has nested nodes:

 <?xml version="1.0"?> <assets> <asset> <asset_name>Home</asset_name> <asset_url>/home</asset_url> <asset_assetid>1</asset_assetid> </asset> <asset> <asset_name>Projects</asset_name> <asset_url>/projects</asset_url> <asset_assetid>2</asset_assetid> <asset> <asset_name>Portfolio</asset_name> <asset_url>/projects/portfolio</asset_url> <asset_assetid>3</asset_assetid> </asset> <asset> <asset_name>Current Jobs</asset_name> <asset_url>/projects/current-jobs</asset_url> <asset_assetid>4</asset_assetid> </asset> </asset> </assets> 

Now I'm starting to add the child nodes of the nodes that I am returning now. Is there a way to iterate over all levels of child nodes in an XML file, even if I don’t know how many levels there are, and add them to my list?

+4
source share
3 answers

So basically what you need to do is a function that accepts each child <asset/> current node, creates the HTML code, then checks to see if the current node has its own <asset/> its own children and continues to recurse deeper the tree.

Here's how you can do it:

 function printAssetMap() { return printAssets(simplexml_load_file(X_ASSETS)); } function printAssets(SimpleXMLElement $parent) { $html = "<ul>\n"; foreach ($parent->asset as $asset) { $html .= printAsset($asset); } $html .= "</ul>\n"; return $html; } function printAsset(SimpleXMLElement $asset) { $html = '<li id="asset'.$asset->asset_assetid.'"><ins>&nbsp;</ins><a href="#">'.$asset->asset_name.' ['.$asset->asset_assetid.']</a>'; if (isset($asset->asset)) { // has <asset/> children $html .= printAssets($asset); } $html .= "</li>\n"; return $html; } 

By the way, I would expect a function called "printX" to actually print or repeat something, but not return it. Perhaps you should call these functions "buildX"?

+8
source

you need to use a recursive function. here is an example that outputs an array from XML. This is from the PHP docs - http://www.php.net/manual/en/ref.simplexml.php . You can change this to list.

 <?php function XMLToArray($xml) { if ($xml instanceof SimpleXMLElement) { $children = $xml->children(); $return = null; } foreach ($children as $element => $value) { if ($value instanceof SimpleXMLElement) { $values = (array)$value->children(); if (count($values) > 0) { $return[$element] = XMLToArray($value); } else { if (!isset($return[$element])) { $return[$element] = (string)$value; } else { if (!is_array($return[$element])) { $return[$element] = array($return[$element], (string)$value); } else { $return[$element][] = (string)$value; } } } } } if (is_array($return)) { return $return; } else { return $false; } } ?> 
+1
source
 <?php function all_nodes($xml){ $all=array(); function add($node){ array_push($all,$node); foreach($node as $child){ add($child); } } add($xml->documentElement); return $all; } ?> 

This will return an array with all nodes in the document.

0
source

Source: https://habr.com/ru/post/1299278/


All Articles