xml to json with attributes for php or python -


i'm trying convert xml json, easy enough php

$file = file_get_contents('data.xml' ); $a = json_decode(json_encode((array) simplexml_load_string($file)),1); print_r($a); 

taking following xml

<?xml version="1.0" encoding="utf-8"?> <foo>     <bar>         <one lang="fr" type="bar">test</one>         <one lang="fr" type="foo">test</one>         <one lang="fr" type="baz">test</one>     </bar>      <thunk>         <thud>             <bar lang="fr" name="bob">test</bar>             <bar lang="bz" name="frank">test</bar>             <bar lang="ar" name="alive">test</bar>             <bar lang="fr" name="bob">test</bar>         </thud>     </thunk>  </foo> 

and paring through simplexml produces

array (     [bar] => array         (             [one] => array                 (                     [0] => test                     [1] => test                     [2] => test                 )          )      [thunk] => array         (             [thud] => array                 (                     [bar] => array                         (                             [0] => test                             [1] => test                             [2] => test                             [3] => test                         )                  )          )  ) 

where ideally output this

{     "foo": {         "bar": {             "one": [                 {                     "_lang": "fr",                     "_type": "bar",                     "__text": "test"                 },                 {                     "_lang": "fr",                     "_type": "foo",                     "__text": "test"                 },                 {                     "_lang": "fr",                     "_type": "baz",                     "__text": "test"                 }             ]         },         "thunk": {             "thud": {                 "bar": [                     {                         "_lang": "fr",                         "_name": "bob",                         "__text": "test"                     },                     {                         "_lang": "bz",                         "_name": "frank",                         "__text": "test"                     },                     {                         "_lang": "ar",                         "_name": "alive",                         "__text": "test"                     },                     {                         "_lang": "fr",                         "_name": "bob",                         "__text": "test"                     }                 ]             }         }     } } 

trouble output doesn't contain attributes child elements, of these elements contain 2 or more attributes, there way transform xml php or python , include attributes found in children?

thanks

in answer i'll cover php, simplexmlelement part of code.

the basic way json encode xml simplexmlelement similar have in question. instantiate xml object , json_encode (demo):

$xml = new simplexmlelement($buffer); echo json_encode($xml, json_pretty_print); 

this produces output close not you're looking already. here simplexml change standard way how json_encode encode xml object.

this can done new subtype of simplexmlelement implementing jsonserializable interface. here such class has default way how php json-serialize object:

class jsonserializer extends simplexmlelement implements jsonserializable {     /**      * simplexmlelement json serialization      *      * @return null|string      *      * @link http://php.net/jsonserializable.jsonserialize      * @see jsonserializable::jsonserialize      */     function jsonserialize()     {         return (array) $this;     } } 

using produce exact same output (demo):

$xml = new jsonserializer($buffer); echo json_encode($xml, json_pretty_print); 

so comes interesting part change serialization these bits output.

first of need differ between whether it's element carrying other elements (has children) or leaf-element of want attributes , text value:

    if (count($this)) {         // serialize children if there children         ...     } else {         // serialize attributes , text leaf-elements         foreach ($this->attributes() $name => $value) {             $array["_$name"] = (string) $value;         }         $array["__text"] = (string) $this;     } 

that's done if/else. if-block children , else-block leaf-elements. leaf-elements easier, i've kept them in example above. can see in else-block iterates on attributes , adds name prefixed "_" , "__text" entry casting string.

the handling of children bit more convoluted need differ between single child element it's name or multiple children same name require additional array inside:

        // serialize children if there children         foreach ($this $tag => $child) {             // child single-named element -or- child multiple elements same name - needs array             if (count($child) > 1) {                 $child = [$child->children()->getname() => iterator_to_array($child, false)];             }             $array[$tag] = $child;         } 

now there special case serialization needs deal with. encode root element name. routine needs check condition (being called document-element) (compare simplexml type cheatsheet) , serialize name under occasion:

    if ($this->xpath('/*') == array($this)) {         // root element needs named         $array = [$this->getname() => $array];     } 

finally left done return array:

    return $array; 

compiled jsonserializer done in simplexml tailored needs. here class , it's invocation @ once:

class jsonserializer extends simplexmlelement implements jsonserializable {     /**      * simplexmlelement json serialization      *      * @return null|string      *      * @link http://php.net/jsonserializable.jsonserialize      * @see jsonserializable::jsonserialize      */     function jsonserialize()     {         if (count($this)) {             // serialize children if there children             foreach ($this $tag => $child) {                 // child single-named element -or- child multiple elements same name - needs array                 if (count($child) > 1) {                     $child = [$child->children()->getname() => iterator_to_array($child, false)];                 }                 $array[$tag] = $child;             }         } else {             // serialize attributes , text leaf-elements             foreach ($this->attributes() $name => $value) {                 $array["_$name"] = (string) $value;             }             $array["__text"] = (string) $this;         }          if ($this->xpath('/*') == array($this)) {             // root element needs named             $array = [$this->getname() => $array];         }          return $array;     } }  $xml = new jsonserializer($buffer); echo json_encode($xml, json_pretty_print); 

output (demo):

{     "foo": {         "bar": {             "one": [                 {                     "_lang": "fr",                     "_type": "bar",                     "__text": "test"                 },                 {                     "_lang": "fr",                     "_type": "foo",                     "__text": "test"                 },                 {                     "_lang": "fr",                     "_type": "baz",                     "__text": "test"                 }             ]         },         "thunk": {             "thud": {                 "bar": [                     {                         "_lang": "fr",                         "_name": "bob",                         "__text": "test"                     },                     {                         "_lang": "bz",                         "_name": "frank",                         "__text": "test"                     },                     {                         "_lang": "ar",                         "_name": "alive",                         "__text": "test"                     },                     {                         "_lang": "fr",                         "_name": "bob",                         "__text": "test"                     }                 ]             }         }     } } 

i hope helpful. it's perhaps little @ once, find jsonserializable interface documented in php manual well, can find more example there. example here on stackoverflow kind of xml json conversion can found here: xml json conversion in php simplexml.


Comments

Popular posts from this blog

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

linux - disk space limitation when creating war file -