Skip to content
Advertisement

How do I loop through a XML file with repeating nodes with PHP

I would like to use PHP to loop through an XML file from an API response, to create an array with the XML folder nodes id and name, sort the array content descending (by id), and echo/return the name content.

XML content:

<?xml version="1.0"?>
<success>
    <document>
        <folder>
            <id>295</id>
            <name>My Folder</name>
            <parent>
                <folder>
                    <id>83</id>
                    <name>Contents</name>
                    <parent>
                        <folder>
                            <id>45</id>
                            <name>Sub Folder</name>
                            <parent>
                                <folder>
                                    <id>21</id>
                                    <name>Root Folder</name>
                                </folder>
                            </parent>
                        </folder>
                    </parent>
                </folder>
            </parent>
        </folder>
    </document>
</success>

I tried a few things myself with SimpleXML but keep getting stuck because the XML output has these nested <parent> nodes and I am not sure how to handle these, to just get the id and name nodes.

This is the PHP part I have so far:

<?php

if (file_exists('api_results.xml')) {
    $xml = simplexml_load_string('api_results.xml');
    
    foreach($xml->document->folder as $folder)
    {
        $folders = array();
        
        foreach($folder as $key => $value)
        {
            $folder[(string)$key] = (string)$value;
        }
        
        $folders[] = $folder;
    }

print_r($folders);
      
} else {
    exit('Failed to open api_results.xml.');
}

How can I create an array and just add each id/name node and then sort the array content?

Advertisement

Answer

You can use XPath, which allows you to search for a list of the <folder> nodes. Using //folder will search at all levels of the document and saves you having to worry about nested foreach loops.

You can then use $folder->id to fetch the <id> element within each <folder>.

One thing is that you should be using simplexml_load_file() to loads data form a file, the string version is designed to load from a string.

$xml = simplexml_load_file('api_results.xml');

$folders = [];
foreach ($xml->xpath('//folder') as $folder) {
    $folders[] = [(string)$folder->id, (string)$folder->name];
}

print_r($folders);

Which for your test document gives…

Array
(
    [0] => Array
        (
            [0] => 295
            [1] => My Folder
        )

    [1] => Array
        (
            [0] => 83
            [1] => Contents
        )

    [2] => Array
        (
            [0] => 45
            [1] => Sub Folder
        )

    [3] => Array
        (
            [0] => 21
            [1] => Root Folder
        )

)
Advertisement