This small library is inspired by another jQuery plugin by Michal Korecki and suited for this Google's specification.
The name of this library comes from 'JavaScript XML Representation' (JXR) or even more correct 'JSON XML Representation'. It may be referred as 'jaxer' but should not be mistaken with jaxer's server by Aptana.
The purpose of the plugin is to help 'translating' JSON to XML which also covers XHTML generation and provide simple but extensible way for 'data JSON' to 'JXR format' transformation using templates.
The specific rules do affect only the keys(tags) when presenting XML in JSON format. They are the following:
$t
(and$text
) does not wrap the value with tags but returns it$c
(and$comment
) does wrap the value with comment tags -<!-- {value} -->
$doctype
adds the value inside a<!DOCTYPE {value}>
tag
One more rule specific to XHTML is served - this is the option to have repeated tags like:
<p>
Text node 1 <br />
<a href="#">Link 1</a> <br />
Text node 2 <br />
<a href="#">Link 2</a>
</p>
As we see this example shows that in a single paragraf we might have several tags of one kind divided by other tags. In JavaScript the key should be unique in the scope of an Object so we can't have the following representation:
var json = {"p" : {
"$t": "Text node 1",
"br": {},
"a": {"href": "#", "$t": "Link 1"},
"br": {},
"$t": "Text node 2",
"br": {},
"a": {"href": "#", "$t": "Link 2"}
}};
Also we know that in XML no tag can have any spaces, so my way of differentiating the nodes is based on existance of a space character in the name of the tag. Anything after a space is trimmed and serves only for uniqueness of the tag in a certain scope. So for example the above will look like:
var json = {"p" : {
"$t 1": "Text node 1",
"br 1": {},
"a 1": {"href": "#", "$t": "Link 1"},
"br 2": {},
"$t 2": "Text node 2",
"br 3": {},
"a 2": {"href": "#", "$t": "Link 2"}
}};
Or:
var json = {"p" : {
"$t 1": "Text node 1",
"br 2": {},
"a 3": {"href": "#", "$t": "Link 1"},
"br 4": {},
"$t 5": "Text node 2",
"br 6": {},
"a 7": {"href": "#", "$t": "Link 2"}
}};
It doesn't matter at all for the converter. But this should be used only when there is real necessity
because in the end you can put even html within a $t
property and then this example might look like:
var json = {"p": "Text node 1 <br \/><a href=\"#\">Link 1<\/a> <br \/> Text node 2 <br \/> <a href=\"#\">Link 2<\/a>"};
The plugin is released under both MIT & GPL licences.
The plugin function exposes a method toXML
added to the global JSON object. It has two arguments:
json
- an JSONML object or array with suchoptions
- object of options controlling the output format, where possible key/values are:newline
(String|default:\n
) - defines the new line in the outputindent
(String|default:isXML
(Boolean|default:false
) - whether to build a pure XML or just a part of itcheckSingleTags
(Boolean|default:true
) - controls the checking of single tags defined in XHTML specification
Because the XHTML specification states that all tags and attributes should be in lower case this is done by the code as 'correction'. Check out the Array example.
var xml = {
"version": "1.0",
"encoding": "UTF-8",
"feed": {
"xmlns": "http://www.w3.org/2005/Atom",
"xmlns$openSearch": "http://a9.com/-/spec/opensearchrss/1.0/",
"xmlns$gd": "http://schemas.google.com/g/2005",
"xmlns$gCal": "http://schemas.google.com/gCal/2005",
"id": {"$t": "...", "$c": "some comment"},
"updated": {"$t": "2006-11-12T21:25:30.000Z"},
"title": {
"type": "text",
"$t": "Google Developer Events"
}
}
};
JSON.toXML(xml, {newline: '', indent: '', isXML: true});
does return:
<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/"
xmlns:gd="http://schemas.google.com/g/2005" xmlns:gcal="http://schemas.google.com/gCal/2005">
<id>...<!-- some comment --></id><updated>2006-11-12T21:25:30.000Z</updated>
<title type="text">Google Developer Events</title></feed>
var xhtml = {
"$doctype": "HTML",
"html": {
"head": {"title": {"$t": "Testing JSON.toXML"}},
"body": {"div": {"$t": "Hello, World!"}}
}
};
JSON.toXML(xhtml, {newline: '', indent: '', isXML: false});
does return:
<!DOCTYPE HTML><html><head><title>Testing JSON.toXML</title></head><body><div>Hello, World!</div></body></html>
var arr = [
{'a': {'href': 'https://github.com', '$t': 'GitHub'}},
{'A': {'HREF': 'http://google.com', '$T': 'Google'}}
];
JSON.toXML(arr, {newline: '', indent: '', isXML: false});
does return:
<a href="https://github.com">GitHub</a><a href="http://google.com">Google</a>
In real life web sites it is very common to have multiple comments and texts divided by other tags but they are all childs of only one tag. To allow this the plugin provides one more specific rule illustrated in this example:
var many_texts = {
"div": {
"$text 1": "text1",
"p": {"$t": "Some content"},
"$text 2": "text2"
}
}
JSON.toXML(many_texts, {newline: '', indent: '', isXML: false});
which returns:
<div>text1<p>Some content</p>text2</div>