user2120765 user2120765 - 1 year ago 135
PHP Question

PHP Simplexml iterator

How to elaborate an array reflecting the structure of the following xml ?

Thanks in advance.

XML source :

<document>
<section type="group" width="100">
<section type="list" width"50"/>
<style>classe1 {color:red}</style>
<section type="text" height="25">azerty</section>
</section>
</document>


Please note the three tags ('section', 'style' then 'section') embedded in the first level 'section'

Example of desired generated array should reflecting this embedding, attributes and tags order :

Array
{
[0]=>Array
{
[key]=>section
[attributes]=>Array
{
[type]=>group
[width]=>100
}
[0]=>Array
{
[key]=>section
[attributes]=>Array
{
[type]=>list
[width]=>50
}
}
[1]=>Array
{
[key]=>style
[content]=>classe1 {color:red}
}
[2]=>Array
{
[key]=>section
[attributes]=>Array
{
[type]=>text
[width]=>25
}
[content]=>azerty
}
}
}


I tried without success whith this code :

<?php
function xml2array($fName)
{
$sxi = new SimpleXmlIterator($fName, null, true);
return sxiToArray($sxi);
}

function sxiToArray($sxi)
{
$a = array();
for( $sxi->rewind(); $sxi->valid(); $sxi->next() )
{
if(!array_key_exists($sxi->key(), $a))
$a[$sxi->key()] = array();
if($sxi->hasChildren())
$a[$sxi->key()][] = sxiToArray($sxi->current());
else
{
$a[$sxi->key() ]['attributs'] = $sxi->attributes();
$a[$sxi->key()][] = strval($sxi->current());
}
}
return $a;
}

try
{
$catArray = xml2array("temp.xml");
echo '<pre>'.print_r($catArray,true);
}
catch(Exception $e)
{
echo 'ERREUR : '.$e->getMessage();
}
?>

Answer Source

I've updated the code to achieve what I think your after. There are a few bits where I've managed the arrays differently. Especially with attributes - I've added them one at a time to allow me to create the key/value setup.

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

function xml2array($fName)
{
    $sxi = new SimpleXmlIterator($fName, null, true);
    $sxi->rewind();
    return sxiToArray($sxi)[0];
}

function sxiToArray($sxi)
{
   $a = array();
   for( $sxi->rewind(); $sxi->valid(); $sxi->next() )
    {
        $newData = [];
        $newData['key'] = $sxi->key();
        foreach ( $sxi->current()->attributes() as $key=>$attribute) {
            $newData['attributes'][(string)$key] = (string)$attribute;
        }
        if($sxi->hasChildren())  {
            $newData = array_merge( $newData, sxiToArray($sxi->current()));
        }
        else
        {
            if ( strlen(strval($sxi->current())) > 0 )    {
                $newData['content'] = strval($sxi->current());
            }
        }
        $a[] = $newData;
    }
    return $a;
}

try
{
    $catArray = xml2array("t1.xml");
    echo '<pre>'.print_r($catArray,true);
}
catch(Exception $e)
{
    echo 'ERREUR : '.$e->getMessage();
}
{
    echo 'ERREUR : '.$e->getMessage();
}

I also had to correct the XML as

<section type="list" width"50"/>

should be

<section type="list" width="50"/>

(missing =)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download