/ Published in: PHP
Was fiddling around at work one day thought this might be useful.
Expand |
Embed | Plain Text
class ArrayToXML { /** * The main function for converting to an XML document. * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document. * * @param array $data * @param string $rootNodeName - what you want the root node to be - defaultsto data. * @param SimpleXMLElement $xml - should only be used recursively * @return string XML */ public static function toXml($data, $rootNodeName = 'data', $xml=null) { // turn off compatibility mode as simple xml throws a wobbly if you don't. if (ini_get('zend.ze1_compatibility_mode') == 1) { ini_set ('zend.ze1_compatibility_mode', 0); } if ($xml == null) { $xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />"); } // loop through the data passed in. foreach($data as $key => $value) { // no numeric keys in our xml please! if (is_numeric($key)) { // make string key... $key = "unknownNode_". (string) $key; } // replace anything not alpha numeric $key = preg_replace('/[^a-z]/i', '', $key); // if there is another array found recrusively call this function if (is_array($value)) { $node = $xml->addChild($key); // recrusive call. ArrayToXML::toXml($value, $rootNodeName, $node); } else { // add single node. $value = htmlentities($value); $xml->addChild($key,$value); } } // pass back as string. or simple xml object if you want! return $xml->asXML(); } }
Comments
Subscribe to comments
You need to login to post a comment.

how do you implement this? where are you connecting to the database table?
This is not a bad little snippet of code, but it has a few drawbacks.
First, it uses Simple XML, which is easier to use than DOMDocument, but is lacking DOMXpath and requires a bit of conversion before you can use it with the XSLTProcessor.
Second, it only lets you fire it off once before returning an XML tree. Further modification is difficult, and would require running it multiple times and then combining the results.
Third, it only supports arrays. Trying to pass a string, can only work if it is an element of the array. If you passed an array of DOMElements, or a mixed collection, or anything besides multidimensional arrays containing only arrays, strings, nulls, or ints, it'll crash.
Fourth, if the array keys are all numeric, it will attempt to add an invalid node to the tree and crash ungracefully.
Fifth, it has no built in support for an XSL driven website and can only be used loosely in conjuction with PHP's XSLTProcessor to that effect.
For an object that fixes all of these issues, check out the DOMi project at http://domi.sourceforge.net - this object is an improved version of DOMDocument, combined with DOMXpath and XSLTProcessor that is built to allow most PHP data structures to be converted to an XML tree flawlessly, lets you run that function multiple times to build up elaborate XML trees, and is designed with XSLTProcessor in mind, and lets you convert from an array to an XML tree and render through the XSLTProcessor in as few as three lines.
In response to my previous comment - ignore item #4. Rereading the code shows me that I missed the section that replaces numeric keys with a string value. However, it will behave oddly. This code replaces "4" with "unknownNode_4" right before removing all non alpha characters, which converts it to "unknownNode".
Hi there, this is an excellent snippet and does the job fantastically when you want to accomplish the simple task of converting an array to XML.
Firstly, make sure you pass the $xml as a reference otherwise the stuff inside the recursive. Here is what I mean:
Secondly, you can't check if a variable is null the way you do. Here is how it should look:
Finally, to implement this in your code can be very straight forward. After you connect to your database and get back your result set as an array run it through this function. I took it out of this wrapper class and stuck it into my MySQL DBI.
Nice piece of code that shortened my way. But visual77 and hradek are both correct with their fixes (var by reference, is_null, wrongly removing non alphas). To sum it up, here is my changed code:
` class ArrayToXML { /** * The main function for converting to an XML document. * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document. * * @param array $data * @param string $rootNodeName - what you want the root node to be - defaultsto data. * @param SimpleXMLElement $xml - should only be used recursively * @return string XML */ public static function toXml($data, $rootNodeName = 'data', &$xml=null) { // turn off compatibility mode as simple xml throws a wobbly if you don't. if (iniget('zend.ze1compatibilitymode') == 1) { iniset ('zend.ze1compatibilitymode', 0); }
} `
Sorry for the mess that Markdown produced from my code. I tried, but it does not get any better. Let's try again with manual formatting...
Nice piece of code that shortened my way. But visual77 and hradek are both correct with their fixes (var by reference, is_null, wrongly removing non alphas). To sum it up, here is my changed code:
Great class with one exception - it doesn't support a common XML structure such as:
The way to represent this in array form would be:
However using the current class this would output:
... which doesn't make a lot of sense.
SO, the class modified to handle the above situation & a non-associative array in a sensible fashion (including above fixes by visual77 and hradek):
Another helpful piece of code to add to this class is the reverse of this function which converts XML (or a SimpleXMLElement object) to an array format which can be converted back using the toXML function:
Ok so the above doesn't work with arrays of arrays ... the correct (and hopefully final! :)) toXML with its corresponding toArray is below. Non-associative arrays are labelled as 'anon' as with Perl's XML::Simple.
I've also included a commented-out little snippet at the bottom which you can use if you want formatted XML thats easy to read (SimpleXMLElement::asXML() returns it all on one line).
I'm using wwwzealdcom's version of this class, it's extremely useful. However, on my version of PHP (5.2.8 Win32), it seems I have to use the following line instead of the simplexmlloadstring("") as in the original post to avoid having FALSE returned instead of a SimpleXMLElement:
$xml = simplexml_load_string("");Oops, the line to use is in fact:
$xml = simplexml_load_string("");(this place needs an edit function)
Not a fan of Markdown, I have to say.
Converted this to a CakePHP helper. Hopefully someone will find this useful.
Save this to 'app/view/helpers/simplexml.php'.
Converted this to a CakePHP helper. Hopefully someone will find this useful.
Save this to 'app/view/helpers/simplexml.php'.
Hi, Thank you for the snippets!
I'd like to use this code in a project that will be open-source, probably using the GPL version 2. Is this OK please, djdykes and others?
Many thanks,
Nick
I've modified @wwwzealdotcom 's code a bit to accept Arrays that can contain a mixture of Arrays and Objects.
`class ArrayToXML { /** * The main function for converting to an XML document. * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document. * * @param array $data * @param string $rootNodeName - what you want the root node to be - defaultsto data. * @param SimpleXMLElement $xml - should only be used recursively * @return string XML */ public static function toXML( $data, $rootNodeName = 'ResultSet', &$xml=null ) {
}`
`class ArrayToXML { /** * The main function for converting to an XML document. * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document. * * @param array $data * @param string $rootNodeName - what you want the root node to be - defaultsto data. * @param SimpleXMLElement $xml - should only be used recursively * @return string XML */ public static function toXML( $data, $rootNodeName = 'ResultSet', &$xml=null ) {
}`
heh.... Sorry for the spamming...
`
Some older versions of PHP the compiled in SimpleXML library does not have the "addChild" function
Here's my version that has a fallback method if you are not in a position to upgrade your PHP and need this to work fast.
class ArrayToXML { /** * The main function for converting to an XML document. * Pass in a multi dimensional array and this recrusively loops through and builds up http://snipplr.com/view/3491/convert-php-array-to-xml-or-simple-xml-object-if-you-wish/an XML document. * * @param array $data * @param string $rootNodeName - what you want the root node to be - defaultsto data. * @param SimpleXMLElement $xml - should only be used recursively * @return string XML */ public static function toXML( $data, $rootNodeName = 'ResultSet', &$xml=null ) {
}
Hi,
I just wrote a simple class to convert array to DOMDocument. Here it is: http://code.google.com/p/array-to-domdocument/.
This is a nice little method. I've added some code to automatically ad cdata if it's not a number:
// add single node. $value = htmlentities($value);