JsonML.org
JSON Markup Language (JsonML)
JsonML (JSON Markup Language) is an application of the JSON (JavaScript Object Notation) format.
The purpose of JsonML is to provide a compact format for transporting XML-based markup as JSON which allows it to be losslessly converted back to its original form.
Native XML/XHTML doesn't sit well embedded in JavaScript.
When XHTML is stored in script it must be properly encoded as an opaque string.
JsonML allows easy manipulation of the markup in script before completely rehydrating back to the original form.
JBST is an MVC-style client-side Ajax templating solution which syntactically feels like JavaServer Pages / ASP.NET UserControls.
It uses JsonML as the encoding and pure JavaScript as the template language.
Once JBST is compiled to JsonML+JavaScript, it may be combined and compressed with all other JavaScript to produce a lightweight templating system with true separation of data and layout.
See it in action.
Links
DUEL
DUEL is the next generation of JBST (JsonML + Browser-Side Template). Templates are written in an improved syntax which can be executed in JavaScript as a client-side template or in Java as a server-side template.
JBST.net
An online JsonML + Browser-Side Template compiler, JBST.net lets you design and compile JBST controls without any server-side components. Quickly turn a static web page into a dynamic web app.
"Get to know JsonML"
A good JsonML article was published on IBM developerWorks. The author walks the reader through some good background on Ajax & JSON before delving into a specific tutorial of JsonML usage.
JsonML in JSON Libraries
Several JSON libraries provide built-in support for JsonML & JBST:
JsonML jQuery Plugin
Trevor Norris put together a jQuery/JavaScript JsonML Plugin which makes JsonML easier to work with within a jQuery-based environment.
Array.prototype.toDomNodes
John Doherty built a light weight JsonML builder alternative.
Alternate XML-to-JsonML XSLT Implementations
Bram Stein has implemented an alternate XSLT for converting arbitrary XML to JSON: xsltjson-lite
XML-to-JsonML Client-Side Proxy
Dominiek ter Heide's XML-to-JSON Proxy is an interesting use of JsonML. The tool enables cross-domain XML service calls without the need for a server-side proxy.
More?
If you have a link relevant to JsonML, send an email to add it to the list.
Topics
JsonML + Browser-Side Templating (JBST) is a client-side templating system utilizing JsonML which demonstrates the strengths of templating in the browser. Leveraging a familiar ASP/JSP syntax, it makes building Ajax solutions much easier.
A primary use for JsonML is to send XHTML across the wire to a JSON-aware client (e.g. web browser) and have it easily parse it into DOM elements. JsonML is an ideal format to transmit UI markup via JSON-RPC. It also provides an excellent mechanism for storing UI markup inside of JavaScript.
See how JsonML can help when building UI in Ajax applications. Also, the JsonML filter callback can easily be used to bind behaviors to DOM elements for implementing techniques such as "Progressive Enhancement".
Learn how any arbitrary XML is transformed into JsonML via a simple XSLT.
For an interesting exercise, see how to convert DOM elements to JsonML and back.
Feedback
Feedback is welcome. If this sounds useful to you, send an email. If you have suggestions which are consistent with the intent here, please feel free to share them.
- Stephen M. McKamey
stephen@jsonml.org
Downloads
- A dual-side (server-side / client-side) template engine is the next evolution of JsonML + Browser-Side Template (JBST):
- DUEL for the JVM
- An open source JsonML + Browser-Side Template (JBST) Compiler:
- JsonFx.NET 1.x for ASP.NET 2.0-3.5
- An open source JsonML builder script:
- JsonML UI Builder: jsonml-html.js
(15.78K uncompressed, 1.94K compact/GZip)
- An open source JBST template data-binding script:
- JBST Data Binder: jsonml-jbst.js
(10.76K uncompressed, 1.07K compact/GZip)
- An open source script which converts DOM elements back into JsonML:
- DOM-to-JsonML Script: jsonml-dom.js
(4.79K uncompressed, 0.85K compact/GZip)
- An open source script which converts any XML-based document into JsonML:
- XML-to-JsonML Script: jsonml-xml.js
(8.8K uncompressed, 1.27K compact/GZip)
- An open source transformation which converts any XML-based document into JsonML:
- XML-to-JsonML XSLT: jsonml.xslt
(6.40K uncompressed)
- An open source utility script for manipulating JsonML structures:
- JsonML Utils Script: jsonml-xml.js
(5.2K uncompressed, 0.58K compact/GZip)
- Open source license
Grammar (BNF)
The following grammar represents how XML-based markup (e.g. XHTML) is encoded into JsonML. As per JSON, whitespace is permitted between tokens.
- element
- = '[' tag-name ',' attributes ',' element-list ']'
- | '[' tag-name ',' attributes ']'
- | '[' tag-name ',' element-list ']'
- | '[' tag-name ']'
- | string
- ;
- tag-name
- = string
- ;
- attributes
- = '{' attribute-list '}'
- | '{' '}'
- ;
- attribute-list
- = attribute ',' attribute-list
- | attribute
- ;
- attribute
- = attribute-name ':' attribute-value
- ;
- attribute-name
- = string
- ;
- attribute-value
- = string
- | number
- | 'true'
- | 'false'
- | 'null'
- ;
- element-list
- = element ',' element-list
- | element
- ;
See the syntax page for more details and the reasoning for this unconventional transformation.
Usage Recommendations
Tuple order: [tag-name, attributes, element-list]
Implementors MUST serialize the tag-name of the element before attributes or before any element-list.
This is because any child text nodes will be siblings to the tag-name of the element.
Implementors MUST serialize attributes before any child element as it is more natural to finish populating element attributes before moving onto other elements.
XML Namespaces
JsonML supports namespaces the same way that namespaces were handled in XML 1.0. The element name is a concatenation of the namespace prefix, the colon ':' character, and the element local-name.
DOM Quirks
While the process is fairly straight forward to recursively hydrate a DOM element tree from JsonML, there are a number of inconsistencies and quirks to be aware of.
- Attribute name differences:
Due primarily to reserved words within JavaScript, there are a number of DOM attributes which have a different name than their XHTML equivalent. e.g. CSS Class attribute is "class" in XHTML and "className" in DOM.
- CSS Style name differences:
Due to reserved words within JavaScript and restrictions upon identifier names, there are a number of DOM styles which have a different name than their CSS equivalent. e.g. the positioning property "float" in CSS is "styleFloat" for IE DOM and "cssFloat" for Firefox DOM. Also, multi-word CSS properties such as "background-color" become camel-case "backgroundColor" in JavaScript.
- Microsoft Internet Explorer TableDOM:
A quirk in IE requires <th> & <td> elements to sit directly within <thead> & <tbody>, respectively. It will not render them if they aren't direct children. As such, implementors should not expect there to be <thead> & <tbody> elements.
- Microsoft Internet Explorer Styles:
IE does not allow inline styles to be set directly on the style property. Implementors must either parse the style attribute and set each style individually, or assign the value to the "cssText" property of the style object.
Colorful Table Example
Rendered in DOM:
#5D28D1 |
Example text here |
#AF44EF |
127310656 |
#AAD034 |
© |
XHTML Markup (516 bytes):
<table class="MyTable" style="background-color:yellow">
<tr>
<td class="MyTD" style="border:1px solid black">
#5D28D1</td>
<td class="MyTD" style="background-color:red">
Example text here</td>
</tr>
<tr>
<td class="MyTD" style="border:1px solid black">
#AF44EF</td>
<td class="MyTD" style="background-color:green">
127310656</td>
</tr>
<tr>
<td class="MyTD" style="border:1px solid black">
#AAD034</td>
<td class="MyTD" style="background-color:blue">
<span style="background-color:maroon">©</span>
</td>
</tr>
</table>
JsonML Markup (558 bytes):
["table",
{
"class" : "MyTable",
"style" : "background-color:yellow"
},
["tr",
["td",
{
"class" : "MyTD",
"style" : "border:1px solid black"
},
"#550758"
],
["td",
{
"class" : "MyTD",
"style" : "background-color:red"
},
"Example text here"
]
],
["tr",
["td",
{
"class" : "MyTD",
"style" : "border:1px solid black"
},
"#993101"
],
["td",
{
"class" : "MyTD",
"style" : "background-color:green"
},
"127624015"
]
],
["tr",
["td",
{
"class" : "MyTD",
"style" : "border:1px solid black"
},
"#E33D87"
],
["td",
{
"class" : "MyTD",
"style" : "background-color:blue"
},
"\u00A0",
["span",
{ "style" : "background-color:maroon" },
"\u00A9"
],
"\u00A0"
]
]
]
Bulleted List Example
Rendered in DOM:
- First Item
- Second Item
- Third Item
XHTML Markup (173 bytes):
<ul>
<li style="color:red">First Item</li>
<li title="Some hover text." style="color:green">
Second Item
</li>
<li><span class="code-example-third">Third</span>
Item</li>
</ul>
JsonML Markup (184 bytes):
["ul",
["li",
{ "style" : "color:red" },
"First Item"
],
["li",
{
"title" : "Some hover text.",
"style" : "color:green"
},
"Second Item"
],
["li",
["span",
{ "class" : "code-example-third" },
"Third"
],
" Item"
]
]