Working with JSON - patzomir/xsparql GitHub Wiki
xsparql:json-doc($url)
: retrieve a JSON doc (or service response) and convert to XML according to these rules:
- the root element is
<jsonObject>
- null objects are represented with attribute
null="true"
- empty arrays are represented with an empty element
- non-empty arrays contain
<arrayElement>
for each array item
Compare the JSON at https://api.opencorporates.com/companies/nl/17087985 (saved as [TODO/test-json.json]; we replaced / with / for readability, and sorted the keys for easier comparison with XML):
{
"api_version": "0.4.6",
"results": {
"company": {
"agent_address": null,
"agent_name": null,
"alternative_names": [],
"branch_status": null,
"company_number": "17087985",
"company_type": "Besloten Vennootschap",
"corporate_groupings": [],
"created_at": "2011-01-12T21:50:57+00:00",
"current_status": null,
"data": {
"most_recent": [
{
"datum": {
"id": 2457732,
"title": "SEC Edgar entry",
"data_type": "OfficialRegisterEntry",
"description": "register id: 1434782",
"opencorporates_url": "https://opencorporates.com/data/2457732"
}
},
{
"datum": {
"id": 2457731,
"title": "Company Address",
"data_type": "CompanyAddress",
"description": "BOKSHEIDE 20, EERSEL P7 5521 PM",
"opencorporates_url": "https://opencorporates.com/data/2457731"
}
}
],
"total_count": 2,
"url": "https://opencorporates.com/companies/nl/17087985/data"
},
...
This simple script [./test-json.xsparql]:
xsparql:json-doc("https://api.opencorporates.com/companies/nl/17087985")
creates the following output [./test-json.xml]:
<jsonObject>
<api_version>0.4.6</api_version>
<results>
<company>
<agent_address null="true"/>
<agent_name null="true"/>
<alternative_names/>
<branch_status null="true"/>
<company_number>17087985</company_number>
<company_type>Besloten Vennootschap</company_type>
<controlling_entity null="true"/>
<corporate_groupings/>
<created_at>2011-01-12T21:50:57+00:00</created_at>
<current_status null="true"/>
<data>
<most_recent>
<arrayElement>
<datum>
<data_type>OfficialRegisterEntry</data_type>
<description>register id: 1434782</description>
<id>2457732</id>
<opencorporates_url>https://opencorporates.com/data/2457732</opencorporates_url>
<title>SEC Edgar entry</title>
</datum>
</arrayElement>
<arrayElement>
<datum>
<data_type>CompanyAddress</data_type>
<description>BOKSHEIDE 20, EERSEL P7 5521 PM</description>
<id>2457731</id>
<opencorporates_url>https://opencorporates.com/data/2457731</opencorporates_url>
<title>Company Address</title>
</datum>
</arrayElement>
</most_recent>
<total_count>2</total_count>
<url>https://opencorporates.com/companies/nl/17087985/data</url>
</data>
...
This XSPARQL function is similar to the XQuery 3.1 standard fn:json-doc() implemented in Saxon 9.7. XQuery can convert JSON to two formats:
- XQuery map:
fn:json-doc()
orfn:parse-json(fn:unparsed-text())
- XML:
fn:json-to-xml(fn:unparsed-text())
Peculiarities:
- Saxon 9.7.0.7 has a bug: all the forms above convert to XQuery map (that can't be serialized), but according to the spec,
fn:json-to-xml
should make XML. This is fixed in 9.7.0.14. - So we use a script like this [./test-json.xq]:
fn:json-to-xml(fn:unparsed-text("http://api.opencorporates.com/companies/nl/17087985"))
- To run it, specify XQuery 3.1, and optionally add indentation for more readable XML
query -qversion:3.1 !indent=true test-json.xq
The result is [./test-json-saxon.xml]:
<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="api_version">0.4.6</string>
<map key="results">
<map key="company">
<string key="name">Bover B.V.</string>
<string key="company_number">17087985</string>
<string key="jurisdiction_code">nl</string>
<null key="incorporation_date"/>
<null key="dissolution_date"/>
<string key="company_type">Besloten Vennootschap</string>
<string key="registry_url">https://server.db.kvk.nl/TST-BIN/FU/TSWS001@?BUTT=17087985</string>
<null key="branch_status"/>
<null key="inactive"/>
<null key="current_status"/>
<string key="created_at">2011-01-12T21:50:57+00:00</string>
<string key="updated_at">2016-05-27T02:27:53+00:00</string>
<string key="retrieved_at">2016-05-27T02:27:53+00:00</string>
<string key="opencorporates_url">https://opencorporates.com/companies/nl/17087985</string>
<map key="source">
<string key="publisher">OpenKVK.nl</string>
<string key="url">https://openkvk.nl/kvk/17087985</string>
<string key="retrieved_at">2016-05-27T02:27:53+00:00</string>
</map>
...