PHPRO.ORG

In a previous example, we saw how to Convert an array to XML Recursively with PHP. In this example, the opposite is done. To convert an XML document to a multidimensional array, and take XML namespaces into account. Here, simpleXmlIterator is your friend and the code has been bundled into an easy to use class to convert any XML string into a array.

An XML String

<movies>
<movie>
<title>Fist Full Of Dollars</title>
<actor>Clint Eastwood</actor>
<actor>Marianne Koch</actor>
<actor> Wolfgang Lukschy</actor>
<director>Sergio Leone</director>
<year>1964</year>
</movie>

<movie>
<title>Fist Full Of Dollars</title>
<actor>Clint Eastwood</actor>
<actor>Klaus Kinski</actor>
<director>Sergio Leone</director>
<year>1965</year>
</movie>

<movie>
<title>The Good The Bad and the Ugly</title>
<actor>Clint Eastwood</actor>
<actor>Lee Van Cleef</actor>
<actor>Eli Wallach</actor>
<director>Sergio Leone</director>
<year>1966</year>
</movie>
</movies>

The code


<?php

class simpleXml2Array
{
    public 
$namespaces$arr;

    public function 
__construct$xmlstring$namespaces=null )
    {
        
$xml = new simpleXmlIterator$xmlstringnull );
        
$this->namespaces is_null$namespaces ) ? null $xml->getNamespacestrue );
        
$this->arr $this->xmlToArray$xml$namespaces );

    }

    
/**
     *
     * @access    public
     * @param    simpleXmlIterator    $xmlstring
     * @param    array            $namespaces
     * @return    array
     *
     */
    
public function xmlToArray$xml$namespaces=null )
    {
        
$a = array();
        
$xml->rewind();
        while( 
$xml->valid() )
        {
            
$key $xml->key();
            if( !isset( 
$a[$key] ) ) 
            {
                
$a[$key] = array(); $i=0
            }
            else
            {
                
$i count$a[$key] );
            }
            
$simple true;
            foreach( 
$xml->current()->attributes() as $k=>$v 
            {
                
$a[$key][$i][$k]=(string)$v;
                
$simple false;
            }

            if( 
$this->namespaces 
            {
                foreach( 
$this->namespaces as $nid=>$name 
                {
                    foreach( 
$xml->current()->attributes$name ) as $k=>$v 
                    {
                        
$a[$key][$i][$nid.':'.$k] =( string )$v;
                        
$simple false;
                    }
                }
            } 
            if( 
$xml->hasChildren() ) 
            {
                if( 
$simple $a[$key][$i] = $this->xmlToArray$xml->current(), $this->namespaces );
                else 
$a[$key][$i]['content'] = $this->xmlToArray$xml->current(), $this->namespaces);
            } 
            else 
            {
                if(
$simple
                {
                    
$a[$key][$i] = strval$xml->current() );
                }
                else 
                {
                    
$a[$key][$i]['content'] = strval$xml->current() );
                }
            }
            
$i++;
            
$xml->next();
        }
        return 
$a;
    }

// end of class

Usage


<?php
$xml 
= new simpleXml2Array$xmlstringnull );

print_r$xml->arr );

Result

Array
(
    [movie] => Array
        (
            [0] => Array
                (
                    [title] => Array
                        (
                            [0] => Fist Full Of Dollars
                        )

                    [actor] => Array
                        (
                            [0] => Clint Eastwood
                            [1] => Marianne Koch
                            [2] =>  Wolfgang Lukschy
                        )

                    [director] => Array
                        (
                            [0] => Sergio Leone
                        )

                    [year] => Array
                        (
                            [0] => 1964
                        )
                )

            [1] => Array
                (
                    [title] => Array
                        (
                            [0] => Fist Full Of Dollars
                        )

                    [actor] => Array
                        (
                            [0] => Clint Eastwood
                            [1] => Klaus Kinski
                        )

                    [director] => Array
                        (
                            [0] => Sergio Leone
                        )

                    [year] => Array
                        (
                            [0] => 1965
                        )
                )

            [2] => Array
                (
                    [title] => Array
                        (
                            [0] => The Good The Bad and the Ugly
                        )

                    [actor] => Array
                        (
                            [0] => Clint Eastwood
                            [1] => Lee Van Cleef
                            [2] => Eli Wallach
                        )

                    [director] => Array
                        (
                            [0] => Sergio Leone
                        )

                    [year] => Array
                        (
                            [0] => 1966
                        )
                )
        )
)