Using annotations to control the automatic conversion from XML to JSON.

The basics

Example 1

Attributes become JSON properties. Elements become JSON properties with an object as value.

<object a="1" b="2">
    <e1 x="1"/>
    <e2 y="1"/>
</object>

JSON:

{"a": "1", "b": "2", "e1": {"x": "1"}, "e2": {"y": "1"}}

Example 2

Elements having no attributes and just one text child, become simple JSON properties (not objects).

<object>
    <e1>1</e1>
    <e2>2</e2>
</object>

JSON:

{"e1": "1", "e2": "2"}

Changing property names

Normally the name of a JSON property is identical to the XML element’s or attribute’s name. However you can use the annotation censhare:_annotation.property_name to enforce a different name.

<object>
    <a censhare:_annotation.property_name="aNew">1</a>
</object>

JSON:

{ "aNew" : "1" }

Arrays

Multiple elements

Multiple sibling elements with same name become a JSON array.

<object>
    <e1 i="1"/>
    <e2 i="1"/>
    <e1 i="2"/>
    <e1 i="3"/>
    <e2 i="2"/>
    <e2 i="3"/>
    <e2 i="4"/>
</object>

JSON:

{"e1": [{"i": "1"}, {"i": "2"}, {"i": "3"}], "e2": [{"i": "1"}, {"i": "2"}, {"i": "3"}, {"i": "4"}]}

You can always force an array by using the annotation censhare:_annotation.multi. This also works for single elements, which otherwise would not become an array, but an object property.

<object>
    <e1 censhare:_annotation.multi="true" i="1"/>
</object>

JSON:

{"e1": [{"i": "1"}]}

Array grouping elements

Often it’s more convenient to group array elements by parent node, which must be tagged with the annotation censhare:_annotation.arraygroup.

<object>
    <elements censhare:_annotation.arraygroup="true">
        <e>1</e>
        <e>2</e>
        <e>3</e>
    </elements>
</object>

JSON:

{ "elements": ["1", "2", "3"]}}

If you omit the annotation the result will look different, since the parent node “elements” becomes a JSON object property, not an array. The name of the array property is then taken from the children elements, “e” in this example.

<object>
    <elements>
        <e>1</e>
        <e>2</e>
        <e>3</e>
    </elements>
</object>

JSON:

{"elements": {"e": ["1", "2", "3"]}}

Multidimensional arrays

Multidimensional arrays (e.g. a matrix) can be created by nesting elements tagged with the annotation censhare:_annotation.arraygroup.

<object>
    <matrix censhare:_annotation.arraygroup="true">
        <e1 censhare:_annotation.arraygroup="true">
            <e>1</e>
            <e>2</e>
        </e1>
        <e1 censhare:_annotation.arraygroup="true">
            <e>3</e>
            <e>4</e>
        </e1>
        <e1 censhare:_annotation.arraygroup="true">
            <e>5</e>
            <e>6</e>
        </e1>
    </matrix>
</object>

JSON:

{"matrix": [["1", "2"], ["3", "4"], ["5", "6"]]}

Data types

JSON supports additional data types besides strings: number, boolean and null. To get property values in the correct data type in the JSON document, use the annotation censhare:_annotation.datatype on text elements to convert the node’s value into the target data type.

<object>
    <string censhare:_annotation.datatype="string">text</string>
    <integer censhare:_annotation.datatype="number">1</integer>
    <double censhare:_annotation.datatype="number">1.2</double>
    <boolean1 censhare:_annotation.datatype="boolean">true</boolean1>
    <boolean2 censhare:_annotation.datatype="boolean">1</boolean2>
    <boolean3 censhare:_annotation.datatype="boolean">false</boolean3>
    <boolean4 censhare:_annotation.datatype="boolean">0</boolean4>
    <null1 censhare:_annotation.datatype="null"/>
    <null2 censhare:_annotation.datatype="null">ignored</null2>
</object>

JSON:

{"string": "text", "integer": 1, "double": 1.2, "boolean1": true, "boolean2": true, "boolean3": false, "boolean4": false, "null1": null, "null2": null}

Note: If you create your XML attributes programmatically using the AXml/CXml Java objects or by an XSLT transformation using xsl:attribute, the type information is correctly stored in the DOM tree and will be used for a subsequent JSON serialization. This means that data type annotations can be omitted in such situations. Just make sure to write the attribute values by using the dedicated Java/XSL types (not as strings). This only works for attribute values and not for text nodes.