0

I have the following array. I'm not even sure if that array is properly formatted. I am not even sure if my array is right.

I want to convert the following array to a serialized XML using PHP. I am using attr tag for the attributes.

Here is the array:

$data = Array(
'name' => 'account',
'attr' => Array(
    'id' => 123456
),
'children' => Array(
    Array(
        'name' => 'name',
        'attr' => Array(),
        'children' => Array(
            'BBC'
        ),
    ),
    Array(
        'name' => 'monitors',
            'attr' => Array(),
        'children' => Array(
            Array(
                'name' => 'monitor',
                'attr' => Array(
                    'id' => 5235632
                ),
                'children' => Array(
                    Array(
                        'name' => 'url',
                        'attr' => Array(),
                        'children' => Array(
                            'http://www.bbc.co.uk/'
                        )
                    )
                )
            ),
            Array(
                'name' => 'monitor',
                'attr' => Array(
                    'id' => 5235633
                ),
                'children' => Array(
                    Array(
                        'name' => 'url',
                        'attr' => Array(),
                        'children' => Array(
                            'http://www.bbc.co.uk/news'
                        )
                    )
                )
            )
        )
    )
)
);
Farid Siddiqui
  • 165
  • 2
  • 2
  • 13
  • Possible duplicate of [How to convert array to SimpleXML](http://stackoverflow.com/questions/1397036/how-to-convert-array-to-simplexml) –  May 15 '16 at 13:27
  • This question isn't that clear - are you just asking whether the array is valid, or how to do an xml conversion? In terms of checking array is valid - i'd just try var_dump($data) and check you get output in the first instance aftering defining it. Running php -l will show if there's a parse error, but not be that helpful locating it. P.S. the array object you post is valid php – Mantis Support May 15 '16 at 13:28
  • how to do xml conversion please – Farid Siddiqui May 15 '16 at 13:29
  • if it is a straight forward array there are many codes available. but my array is all over the place and I can't figure out how to manage it. – Farid Siddiqui May 15 '16 at 13:33

3 Answers3

2

It is quite easy with a recursive function. Your basic array contains 3 elements, the name, the attribute list and the children. So your function has to create and append a node with the name, set all attributes and iterate the child data. If the child is an scalar it is a text node, for an array call the function itself.

function appendTo($parent, $data) {
  $document = $parent->ownerDocument ?: $parent; 
  $node = $parent->appendChild($document->createElement($data['name']));
  if (isset($data['attr']) && is_array($data['attr'])) {
    foreach ($data['attr'] as $name => $value) {
      $node->setAttribute($name, $value);
    }
  }  
  if (isset($data['children']) && is_array($data['children'])) {
    foreach ($data['children'] as $name => $childData) {
      if (is_scalar($childData)) {
        $node->appendChild($document->createTextNode($childData));
      } elseif (is_array($childData)) {
        appendTo($node, $childData);
      }
    }
  }
}

$document = new DOMDocument();
$document->formatOutput = TRUE;
appendTo($document, $data);

echo $document->saveXml();

Output:

<?xml version="1.0"?>
<account id="123456">
  <name>BBC</name>
  <monitors>
    <monitor id="5235632">
      <url>http://www.bbc.co.uk/</url>
    </monitor>
    <monitor id="5235633">
      <url>http://www.bbc.co.uk/news</url>
    </monitor>
  </monitors>
</account>
ThW
  • 19,120
  • 3
  • 22
  • 44
1

Try the following function

function assocArrayToXML($root_element_name,$ar)
{
    $xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
    $f = function($f,$c,$a) {
            foreach($a as $k=>$v) {
                if(is_array($v)) {
                    $ch=$c->addChild($k);
                    $f($f,$ch,$v);
                } else {
                    $c->addChild($k,$v);
                }
            }
    };
    $f($f,$xml,$ar);
    return $xml->asXML();
} 


echo assocArrayToXML("root",$data);

test it here

  • Don't use `create_function()` it is an hidden `eval()`. Use an [anonymous function](http://www.php.net/manual/en/functions.anonymous.php). – ThW May 15 '16 at 14:07
  • @ThW can you please remove the down-vote, this could have just been asked as a comment –  May 15 '16 at 14:23
  • The output from you method is still broken XML. You have numeric tag names. *btw* Try using it an url with a `&` in it. – ThW May 16 '16 at 13:08
  • Yes i know @ThW you are right it does not produce the xml the way the OP finally wants it. It is rather a quick function to convert an array to xml. I will probably edit or add an alternative solution. –  May 16 '16 at 16:49
0

Hope this will help.

<?php
function array2xml($arr)
{
    $dom = new DomDocument('1.0');
    /*
    *Create Root
    */  
    $root = $dom->createElement($arr['name']);
    if(isset($arr['attr']) && !empty($arr['attr']))
    {
        foreach($arr['attr'] as $key=>$val)
        $root->setAttribute($key, $val); 
    }
    $root = $dom->appendChild($root);
    createChilds($arr['children'], $dom, $root);

    header('Content-type: text/xml');
    echo $dom->saveXML(); 
}
function createChilds($arr, $dom, $parent)
{
    foreach($arr as $child)
    {
        if(isset($child['name']))
            $node = $dom->createElement($child['name']);
        /*
        *Add Attributes
        */
        if(isset($child['attr']) && !empty($child['attr']))
        {
            foreach($child['attr'] as $key=>$val)
            $node->setAttribute($key, $val); 
        }
        /*
        *Add Childs Recursively
        */      
        if(isset($child['children']) && is_array($child['children']))
        {
            createChilds($child['children'], $dom, $node);
        }
        else if(isset($child) && is_string($child))
        {
            $text = $dom->createTextNode($child); 
            $parent->appendChild($text); 
        }
        if(isset($node))
        $parent->appendChild($node);
    }
}

$data = Array(
'name' => 'account',
'attr' => Array(
    'id' => 123456
),
'children' => Array(
    Array(
        'name' => 'name',
        'attr' => Array(),
        'children' => Array(
            'BBC'
        ),
    ),
    Array(
        'name' => 'monitors',
            'attr' => Array(),
        'children' => Array(
            Array(
                'name' => 'monitor',
                'attr' => Array(
                    'id' => 5235632
                ),
                'children' => Array(
                    Array(
                        'name' => 'url',
                        'attr' => Array(),
                        'children' => Array(
                            'http://www.bbc.co.uk/'
                        )
                    )
                )
            ),
            Array(
                'name' => 'monitor',
                'attr' => Array(
                    'id' => 5235633
                ),
                'children' => Array(
                    Array(
                        'name' => 'url',
                        'attr' => Array(),
                        'children' => Array(
                            'http://www.bbc.co.uk/news'
                        )
                    )
                )
            )
        )
    )
)
);
array2xml($data);
?>
  • where is the explanation? please add some point or comments too to make your code self-explanatory. – surajs1n May 15 '16 at 14:41