JSON-to-XML - harder stuff

2008-02-02 @ 08:57#

i continue to beat up my JSON-to-XML service today. as i mentioned in my previous post, i'm building this service so that i can consistently convert incoming JSON strings (from PUT/POST into a valid XML document. that's because my exyus engine uses XML documents to validate (via XSD) and transform (via XSLT) data into whatever representation(s) i need. so this is all about utility and consistency.

anyway, here's a couple other examples of output from my utility. first, a JSON string that contains and array *and* at least one name that is an invalid XML name (due to use of namespace):

{'tasks' :
{ 'xml:base':'http://localhost/xcs/tasklist/',
'task' : [
{'id' : 'x8ca2f68ed5464b2', 'seq' : '1', 'name' : 'Read Mike\'s TaskList Tutorial', 'is-completed' : '1'}
,
{'id' : 'x8ca2f68f058de9a', 'seq' : '2', 'name' : 'Download Exyus', 'is-completed' : '0'}
,
{'id' : 'x8ca2f68f623d546', 'seq' : '3', 'name' : 'Install and run examples', 'is-completed' : '0'}
,
{'id' : 'x8ca2f690144ef64', 'seq' : '4', 'name' : 'Use Exyus to build my own cool app', 'is-completed' : '0'}
]
}
}

<root>
  <tasks>
    <task>
      <item>
        <is-completed>1</is-completed> 
        <name>Read Mike's TaskList Tutorial</name> 
        <seq>1</seq> 
        <id>x8ca2f68ed5464b2</id> 
      </item>
      <item>
        <is-completed>0</is-completed> 
        <name>Download Exyus</name> 
        <seq>2</seq> 
        <id>x8ca2f68f058de9a</id> 
      </item>
      <item>
        <is-completed>0</is-completed> 
        <name>Install and run examples</name> 
        <seq>3</seq> 
        <id>x8ca2f68f623d546</id> 
      </item>
      <item>
        <is-completed>0</is-completed> 
        <name>Use Exyus to build my own cool app</name> 
        <seq>4</seq> 
        <id>x8ca2f690144ef64</id> 
      </item>
    </task>
    <xml_base>http://localhost/xcs/tasklist/</xml_base> 
  </tasks>
</root>

not bad. notice the use of the item elements for each member of an array. this is a bit of 'cruft', but it makes logical sense and eases the recursion work i need to do to interpret the JSON string. also note that the incoming "xml:base" has been converted to "xml_base". technically, this is not an invalid XML element name, but i have way to easily sort out XML namespaces in JSON strings[!] so i just convert it.

ok, now how about something a bit more challenging. this is an extensive example i found while researching the rules for JSON serialization. check this out:

{
    "this test"  : true,
    "ThreeDSort" : {
        z : 9.323
    },
    "x y" : "x y",
    yPos  : {
        "inner"  : [2,4],
        "outer"  : [4,8,4,8]
    },
    "props": [ true, null, false],
    "oldVals": [ "oldvals1", {innermost:"old+inner"}, "oldvals3"],
    y1   : {
        z  : "value"
    },
    "xy and z": "xy and z",
    y3   : {
        z2  : "z2"
    }
};

<root>
  <xy_x0020_and_x0020_z>xy and z</xy_x0020_and_x0020_z> 
  <ThreeDSort>
    <z>9.323</z> 
  </ThreeDSort>
  <props>
    <item>True</item> 
    <item>null</item> 
    <item>False</item> 
  </props>
  <x_x0020_y>x y</x_x0020_y> 
  <oldVals>
    <item>oldvals1</item> 
    <item>
      <innermost>old+inner</innermost> 
    </item>
    <item>oldvals3</item> 
  </oldVals>
  <this_x0020_test>true</this_x0020_test> 
  <y3>
    <z2>z2</z2> 
  </y3>
  <yPos>
    <outer>
      <item>4</item> 
      <item>8</item> 
      <item>4</item> 
      <item>8</item> 
    </outer>
    <inner>
      <item>2</item> 
      <item>4</item> 
    </inner>
  </yPos>
  <y1>
    <z>'f'f''</z> 
  </y1>
</root>

wow! lots going on there. note the conversion of invalid XML names using the standard XML method of 'escaping' the invalid characters w/ unicode hex. not pretty but standard and safe. lots of nesting; several arrays, etc. mind you, this is 'scary' XML, but it's valid. that's my goal.

i am finishing up the testing and code clean up today. i'll post the bits into the exyus googlecode this weekend. and i should have support for incoming JSON before the start of next week.

code