fluidxml
fluidxml copied to clipboard
Export XML to array() or stdClass objects
It would be nice to be able to export to arrays or stdClass Objects
eg.
$xml = <<<XML
<animal operation="create">
<type>Herbivore</type>
<attribute>
<legs>4</legs>
<head>1</head>
</attribute>
</animal>
XML;
// IMPORT
$doc = new FluidXml($xml);
// EXPORT
$arr = $doc->exportArray();
// ARRAY
var_export($arr);
Array (
'animal' => Array (
'@operation' => 'create',
'type' => 'Herbivore',
'attribute' => Array(
'legs' => 4,
'head' => 1
)
)
)
Would like to hear if this could be implemented.
Thanks
Or perhaps I should use PEAR::XML_Serializer ?
How would namespaces be treated in the expected output?
E.g.
<animal operation="create">
<type>Herbivore</type>
<attribute xmlns:foo="http://namespace.foo">
<foo:legs>4</foo:legs>
<foo:head>1</foo:head>
</attribute>
</animal>
To convert a XML into a ARRAY is easy
$sxml = simplexml_load_string($xmlcontent);
$array = json_decode(json_encode($sxml), true);
With this we get the array that represents the XML.
But FluidXML does not do the reverse, becose the structure of the attributes does not follow the same rule, in the case of SimpleXML the attributes are created in this way:
'infNFe' => [
'@attributes' => [
'Id' => 'NFe35150258716523000119550000000344891840634422',
'versao' => '2.00'
],
NOTE: this is easily to correct! In addition SimpleXML saves repeated tags as a subarrays not replicate the tag name, like:
'det' => [ 0 => [ others tag for det node 0],
1 => [ others tag for det node 1],
In FluidXML this tag 'det' after 0 is ignored and puts all nodes in first 'det', i dont know correct this
All xml with which I read are big and we can say a little complex see in sped-nfe
@alepeino As far as I can tell, there's no special notation for namespaces.
So maybe we can reuse the attribute notation:
Array (
'animal' => Array (
'@operation' => 'create',
'type' => 'Herbivore',
'attribute' => Array(
'@xmlns:foo' => 'http://namespace.foo'
'legs' => 4,
'head' => 1
)
)
)
@denormalizer Namespaces are special in that xmlns:foo
lets you create a sort of prefix alias for the scope of the declaring element and its descendants. So, in my example, both <legs/>
and <head/>
belong in the http://namespace.foo
namespace, but your example does not represent that.
I'm not saying it's not doable, but it may be not as straightforward as one may think.
Sorry I didn't see your namespaces in the child nodes.
For simplicity, I suggest the following:
Array (
'animal' => Array (
'@operation' => 'create',
'type' => 'Herbivore',
'attribute' => Array(
'@xmlns:foo' => 'http://namespace.foo'
'foo:legs' => 4,
'foo:head' => 1
)
)
)
That means the translator is namespace agnostic. It is up to the user to generate the correct format.
My Working implementation using XML_Unserialize (http://pear.php.net/package/XML_Serializer/)
Where $xml
is the xml string by @alepeino above. And $arr
is the array generated by myself above:
// INITIALIZE
$unserializer = new XML_Unserializer();
// SET OPTIONS
$unserializer->setOption('complexType', 'array');
$unserializer->setOption('parseAttributes', true);
$unserializer->setOption('prependAttributes', '@');
// UNSERIALIZE
$unserializer->unserialize($xml);
// ARRAY DATA
$arr = $unserializer->getUnserializedData();