edit
A similar method is advocated on http://www.jsonml.org/. They coined the term json markup language.
You can pick any mapping you like, but if you map
<el attr="value">
txt
</el>
to
{"el":{"attr":"value","content":"txt"}}
then how would you map:
<el attr="value" content="txt1">txt2</el>
I'd make use of the fact that some attibute names are forbidden.
{"el":{"attr":"value", "content":"txt1", "":["txt"]}
Or a more compex example:
<widget>
<debug>on</debug>
<window title="Sample Konfabulator Widget">
I just put some text here
<name>main_window</name>
<width>500</width>
<height>500</height>
</window>
<image src="Images/Sun.png" name="sun1">
<hOffset>250<unit>mm</unit></hOffset>
<vOffset>250</vOffset>
<alignment>center</alignment>
</image>
</widget>
could map to:
{"widget":{"":[
{"debug":{"":["on"]}},
{"window":{"title":"Sample Konfabulator Widget", "": [
"I just put some text here",
{"name":{"":["main window"]}},
{"width":{"":["500"]}},
{"height":{"":["500"]}}
]},
{"image":{"src":"Images/Sun.png", "name":"sun1", "":[
{"hOffset":{"":["250",{"unit":{"":["mm"]}}]}},
{"vOffset":{"":["250"]}},
{"alignment":{"":["center"]}}
}
]}
The rules for this conversion are unambiguous:
- an element is converted to an object.
- The object key is the element name.
- The object value is an object itself, with:
- an attibute is mapped to an object property. (key/value)
- the object content is mapped to a special property.
- The special property name is an empty string. This can never collide with an xml attribyte name.
- The special property value is an array.
- Within the array, plain text is represented as a string.
- Within the array, elements are represented as objects, as described above.
To safe space, there is a way to unambigously simplify mentioned mapping:
{"widget":{"":[
{"debug":"on"},
{"window":{"title":"Sample Konfabulator Widget", "": [
"I just put some text here",
{"name":"main window"},
{"width":"500"},
{"height":"500"}
]},
{"image":{"src":"Images/Sun.png", "name":"sun1", "":[
{"hOffset":["250",{"unit":"mm"}]},
{"vOffset":"250"},
{"alignment":"center"}
}
]}
If an element doesn't have any attibutes, the value object (containing the special empty string mapping to an array) is replaced by the array directly. So instead of:
{"hOffset":{"":["250",{"unit":{"":["mm"]}}]}}
you get
{"hOffset":["250",{"unit":["mm"]}]}
If the element content is just text, the array containing the string value is replaced by the string value directly, so you get:
{"hOffset":["250",{"unit":"mm"}]}
This way, there will always be exactly one way to map the jml (json markup language) back to xml (or html)