XML into Associative Array using PHP

here's my function to generate associated array, derived from

Recursive cast from SimpleXMLObject to Array

function xml2assoc($obj, &$arr) {
  $children = $obj->children();
  foreach ( $children as $elementName => $node ) {

    if (!isset($arr[$elementName])) {
      $arr[$elementName] = array();
    }
    $temp = array();
    $attributes = $node->attributes();
    foreach ( $attributes as $attributeName => $attributeValue ) {
      $attribName = strtolower(trim((string) $attributeName));
      $attribVal = trim((string) $attributeValue);
      $temp[$attribName] = $attribVal;
    }
    $text = (string) $node;
    $text = trim($text);
    if (strlen($text) > 0) {
      $temp ['text='] = $text;
    }
    $arr[$elementName][] = $temp;
    $nextIdx = count($arr[$elementName]);
    xml2assoc($node, $arr[$elementName][$nextIdx - 1]);
  }
  return;
}

$xml = '<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>2</ArticleCount>
<Articles>
<item>
<Title><![CDATA[title1]]></Title> 
<Description><![CDATA[description1]]></Description>
<PicUrl><![CDATA[picurl]]></PicUrl>
<Url><![CDATA[url]]></Url>
</item>
<item>
<Title><![CDATA[title]]></Title>
<Description><![CDATA[description]]></Description>
<PicUrl><![CDATA[picurl]]></PicUrl>
<Url><![CDATA[url]]></Url>
</item>
</Articles>
</xml> ';

$dom = new SimpleXMLElement($xml);

$arr = array();

xml2assoc($dom, $arr);
print_r($arr);

generated array:

Array
(
    [ToUserName] => Array
        (
            [0] => Array
                (
                    [text=] => toUser
                )

        )

    [FromUserName] => Array
        (
            [0] => Array
                (
                    [text=] => fromUser
                )

        )

    [CreateTime] => Array
        (
            [0] => Array
                (
                    [text=] => 12345678
                )

        )

    [MsgType] => Array
        (
            [0] => Array
                (
                    [text=] => news
                )

        )

    [ArticleCount] => Array
        (
            [0] => Array
                (
                    [text=] => 2
                )

        )

    [Articles] => Array
        (
            [0] => Array
                (
                    [item] => Array
                        (
                            [0] => Array
                                (
                                    [Title] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => title1
                                                )

                                        )

                                    [Description] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => description1
                                                )

                                        )

                                    [PicUrl] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => picurl
                                                )

                                        )

                                    [Url] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => url
                                                )

                                        )

                                )

                            [1] => Array
                                (
                                    [Title] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => title
                                                )

                                        )

                                    [Description] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => description
                                                )

                                        )

                                    [PicUrl] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => picurl
                                                )

                                        )

                                    [Url] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [text=] => url
                                                )

                                        )

                                )

                        )

                )

        )

)

This worked great for me, and it was simple.

$ob = simplexml_load_file('test.xml');
$json = json_encode($ob);
$array = json_decode($json, true);

One example could be:

$dom = new DOMDocument;
$dom->loadXML(
    '<root>
        <Computer id="1">   
            <OS>
                <Name>Linux</Name>
                <Age>Older than me</Age>
            </OS>
        </Computer>

        <Computer id="2">
            <OS>
                <Name>Windows</Name>
                <Age>Not so much</Age>
            </OS>
        </Computer>
    </root>'
);

$xpath = new DOMXPath($dom);
$result = array();

foreach ($xpath->query('//*[count(*) = 0]') as $node) {
    $path = array();
    $val = $node->nodeValue;

    do {
        if ($node->hasAttributes()) {
            foreach ($node->attributes as $attribute) {
                $path[] = sprintf('%s[%s]', $attribute->nodeName, $attribute->nodeValue);
            }
        }
        $path[] = $node->nodeName;
    }
    while ($node = $node->parentNode);

    $result[implode('/', array_reverse($path))] = $val;
}

print_r($result);

Output:

Array
(
    [#document/root/Computer/id[1]/OS/Name] => Linux
    [#document/root/Computer/id[1]/OS/Age] => Older than me
    [#document/root/Computer/id[2]/OS/Name] => Windows
    [#document/root/Computer/id[2]/OS/Age] => Not so much
)

Thats not exactly what you're looking for, but it's a start and can easily be tweaked to give different results.


Read the xml into a DOM object, loop through it, save results into an array. Is that simple.

Tags:

Php

Xml

Arrays