XML vs JSON - differences
Introduction
Before COMPASS 5.4 all communication with COMPASS was via XML. Since 5.4, and mainly the introduction of REST Services, JSON is an alternative format for the exchange of information.
For backwards compatibility several of the services return the response information in two formats: JSON and XML.
E.g. the REST services /assessment and /assessmentXML.
Both services have the same input, but one returns the traditional XML, while the other returns JSON.
This JSON has been converted from XML via org.json.XML.toJSONObject(xml).
Therefore some information is formatted differently as in XML. These differences are described in JSON as response structure
Then there are certain services that accept a JSON body. The chapter [JSON as body of the service] points out the differences.
JSON as response structure
Every XML of COMPASS uses XML attributes to transport values. I.e. it does not use child elements to transport the value. For explanation see the following example:
The name James Bond passed as a child XML element (not used in COMPASS' XML):
<person age="33">
<name>James Bond</name>
</person>
The name passed as an XML attribute (used in COMPASS' XML):
<person age="33" name="James Bond">
</person>
Therefore all values in COMPASS' XML are passed within quotation marks, independently on whether they are numbers, boolean values, strings, or other data types.
As described above, the JSON is converted from the XML by the method org.json.XML.toJSONObject(xml), which converts the XML to JSON in a default way:
-
Values that are recognised as numbers are displayed without quotation marks.
-
Similarly the values true and false are recognised as boolean values, and represented without quotation marks.
-
Other values are interpreted as strings, and represented with quotation marks.
For example
<numberInput maxVal="300" mandatory="true" id="158" minVal="1" error="false" editable="true">
<value id="1257" value="177"></value>
<unit name="cm" id="13"></unit>
</numberInput>
becomes
"numberInput": {
"unit": {
"name": "cm",
"id": 13
},
"maxVal": 300,
"minVal": 1,
"editable": true,
"id": 158,
"error": false,
"mandatory": true,
"value": {
"id": 1257,
"value": 177
}
}
Another important difference is that in the XML certain elements can exist 0, 1 or many times. The conversion engine can’t know without further information, that multiple instances are possible.
For example an item (here ScreenBuilder 2) can contain 1 or many questions.
-
When there are 2 or more
questionsin the XML, they are converted into aquestionarray:
"item": [
{
"personName": "Meier",
"current": true,
"question": [
{
"catyID": 231,
...
"id": "X_33#_100#3_231",
"text": {
"text": "Have you regularly smoked in the last 12 months?",
"error": false
},
"cotyID": 27,
"order": 1
},
{
"catyID": 158,
...
"id": "X_3#_100#3_158",
"text": {
"text": "What is your height?",
"error": false
},
"cotyID": 27,
"order": 2
}
],
"name": "3. Your Lifestyle Meier",
"consistent": true
}
]
-
When there is exactly 1
questionin the XML, the JSONquestionbecomes one element:
"item": [
{
"personName": "Meier",
"current": true,
"question": {
"catyID": 231,
...
"id": "X_33#_100#3_231",
"text": {
"text": "Have you regularly smoked in the last 12 months?",
"error": false
},
"cotyID": 27,
"order": 1
},
"name": "3. Your Lifestyle Meier",
"consistent": true
}
]
-
When there no
questionin the XML, the JSON doesn’t include aquestionelement.
The mentioned difference can happen for any element that can appear once or more in the XML.
For the ScreenBuilder 2 protocol this can happen for the XML elements question, item, person and others.
When parsing the received JSON be prepared to sometimes find an element and sometimes an array of elements!
JSON as body of a service
There are a variety of service that accept or need a JSON Body. Most of these bodies aren’t more than an array of attributes, and need no further explanation than the one available in the Swagger documentation.
E.g. the printApplication service requires the following Body:
{
"caseId": "CASE_011",
"subId": "TEST",
"sourceType": "22",
"group": true,
"language": "en",
"textType": "XML"
}
Then there are bodies that accept a JSON structure that corresponds to an existing XML structure. Such JSON elements have to be explained, as the vary from the XML syntax.
Currently the only service of this type is the userAction service.
userAction
A XML userAction can contain 0, 1 or many answer elements. And each of those answer elements can contain 0, 1 or more value-elements.
Each answer element has a mandatory question attribute.
The following example shows such a userAction:
<userAction screenCommand="_2" screenID="_105">
<answer question="_20">
<value id="1006" value="Diving with mixed gas tanks Nitrox"></value>
<value id="1007" value="Diving with oxygen tanks"></value>
</answer>
<answer question="_1">
<value id="158" value="178" unit="13"></value>
</answer>
<answer question="_2">
<value id="1258" value="80" unit="6"></value>
</answer>
</userAction>
Please note that for version 2 of the Screenbuilder-protocol (SB2), there is only one answer-element allowed per userAction.
Should you have to pass JSON instead of XML, then you have to take into account the following differences:
-
the
userActionelement becomes superfluous, as the service is dedicated only to userActions -
the
userActionattributesscreenCommandandscreenIDremain attributes of the main JSON structure, together with the attributescaseIdandsubIdof thefullRequest. -
each XML
answerelement becomes an element of the JSONanswersArray -
each XML
valueelement becomes an element of the JSONvaluesArray -
the XML
questionattribute becomes the JSONquestionIdattribute
The following example shows the JSON body of the userAction service, corresponding to the example above:
{
"screenCommand": "_2",
"screenId": "_105",
"caseId": "xxxxx",
"subId": "YYYY",
"answers": [
{
"questionId": "_20",
"values": [
{
"id": "1006",
"value": "Diving with mixed gas tanks Nitrox"
},
{
"id": "1007",
"value": "Diving with oxygen tanks"
}
]
},
{
"questionId": "_1",
"values": [
{
"id": "158",
"value": "178",
"unit": "13"
}
]
},
{
"questionId": "_2",
"values": [
{
"id": "1258",
"value": "80",
"unit": "6"
}
]
}
]
}