note 103173 deleted from book.simplexml by danbrown
| From: | danbrown@php.net | Date: | Wed, 06 Apr 2011 14:16:12 +0000 |
| Subject: | note 103173 deleted from book.simplexml by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-178562@lists.php.net to get a copy of this message | ||
Note Submitter: marcus dot garcia at uol dot com dot br
----
It's IMPRESSIVE how people like to post half-assed functions in here, spreading broken code
like a virus, just like svdmeer at xs4all dot nl and many others below.
Well, here's decente version of xml2array, working AND keeping all the attributes. also taking
account of duplicated names etc:
<?php
function xml2array($xml) {
if(get_class($xml) != 'SimpleXMLElement') {
$xml = simplexml_load_string($xml);
}
if(!$xml) {
return false;
}
$main = $xml->getName();
$arr = array();
$nodes = $xml->children();
foreach($nodes as $node) {
$nodeName = $node->getName();
$nodeAttributes = $node->attributes();
$attributesArray = array();
foreach($nodeAttributes as $attributeName => $attributeValue) {
$attributesArray[$attributeName] = (string) $attributeValue;
}
$nodeValue = sizeOf($node->children()) == 0 ? trim($node) : xml2array($node);
if(!isSet($arr[$nodeName]['value'])) {
$arr[$nodeName]['value'] = $nodeValue;
$arr[$nodeName]['attributes'] = $attributesArray;
} else {
if(!is_array($arr[$nodeName]['value'])) {
$arr[$nodeName]['value'][] = array_shift($arr[$nodeName]);
$arr[$nodeName]['attributes'][] =
array_shift($arr[$nodeName]['attributes']);
}
$arr[$nodeName]['value'][] = $nodeValue;
$arr[$nodeName]['attributes'][] = $attributesArray;
}
}
return($arr);
}
?>
So the code above does exactly what it's supposed to do: Take a XML string and return an array
out of that;
Returns false if the XML is not valid or parseable by SimpleXML for any reason, else, returns an
array containing the nodes of the XML, keeping in mind:
It's not an array of Name => Value
It IS an array of
(String) Node name = {
Value = String (node value) OR Array(inner nodes)
Attributes = {
(String) Atribute name 1 = (String) attribute value
(String) Atribute name 2 = (String) attribute value
}
}
An example of:
<?xml version="1.0" encoding="UTF-8"
standalone="yes"?><main>
<inner abc="def" ghi="jkl">
<innerInner>text</innerInner>
<innerInner_DUP kkk="lll">text</innerInner_DUP>
<innerInner_DUP xtz="ztx" zzz="xxx">text</innerInner_DUP>
</inner>
<inner2>
<innerInner2 abc="def">text2</innerInner2>
</inner2>
</main>
Will return this:
Array
(
[inner] => Array (
[value] => Array (
[innerInner] => Array (
[value] => text
[attributes] => Array ( )
)
[innerInner_DUP] => Array (
[attributes] => Array (
[0] => lll
[1] => Array
(
[xtz] => ztx
[zzz] => xxx
)
)
[value] => Array (
[0] => text
[1] => text
)
)
)
[attributes] => Array (
[abc] => def
[ghi] => jkl
)
)
[inner2] => Array (
[value] => Array (
[innerInner2] => Array (
[value] => text2
[attributes] => Array (
[abc] => def
)
)
)
[attributes] => Array ( )
)
)
Which preserves every single node name, value and attributes of the XML, which i find years ahead of
half-assed implementations with variable naming such as $t .
Keeps everything easy to understand, structurally correct etc.