Home > jxr

jxr

Jxr is a project mainly written in JavaScript, it's free.

JXR is a simple library for JSON data transformation and conversion to XML/XHTML

Inspiration

This small library is inspired by another jQuery plugin by Michal Korecki and suited for this Google's specification.

Naming

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.

Purpose

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.

JXR format

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

Weak format

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>"};

Licence

The plugin is released under both MIT & GPL licences.

TODO: update everything below

Function Docs

The plugin function exposes a method toXML added to the global JSON object. It has two arguments:

  • json - an JSONML object or array with such
  • options - object of options controlling the output format, where possible key/values are:
    • newline (String|default: \n) - defines the new line in the output
    • indent (String|default: ` `) - defines the identation of the inner tags (cumulative)
    • isXML (Boolean|default: false) - whether to build a pure XML or just a part of it
    • checkSingleTags (Boolean|default: true) - controls the checking of single tags defined in XHTML specification

Note

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.

Examples

XML 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>

XHTML example (with HTML5 doctype)

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>

Array example

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>

Repeatable tags example

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>