Structure QL, not to be confused with Structured Query Language (SQL) (Could not come up with a better name for now). Is a small frame work targeted at enabling REST/HTTP framworks to ease implementation of partial returns based on structured data, currently aimed specifically at JSON.
Given the following JSON:
{
"id": "GPL-2.0",
"identifiers": [
{
"identifier": "GPL-2.0",
"scheme": "DEP5"
},
{
"identifier": "GPL-2.0",
"scheme": "SPDX"
},
{
"identifier": "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"scheme": "Trove"
}
],
"links": [
{
"note": "tl;dr legal",
"url": "https://tldrlegal.com/license/gnu-general-public-license-v2"
},
{
"note": "Wikipedia page",
"url": "https://en.wikipedia.org/wiki/GNU_General_Public_License"
},
{
"note": "OSI Page",
"url": "https://opensource.org/licenses/GPL-2.0"
}
],
"name": "GNU General Public License, Version 2.0",
"other_names": [],
"superseded_by": "GPL-3.0",
"keywords": [
"osi-approved",
"popular",
"copyleft"
],
"text": [
{
"media_type": "text/plain",
"title": "Plain Text",
"url": "https://www.gnu.org/licenses/gpl-2.0.txt"
},
{
"media_type": "text/html",
"title": "HTML",
"url": "https://www.gnu.org/licenses/gpl-2.0-standalone.html"
}
]
}
Using DotJEM.StructureQL.Json, we can query into the document with the following queries:
**Return the entire document: **
**
or {**}
Return only top level primitive fields:
*
or {*}
Code
JObject result = json.Query("*");
Result:
{
"id": "GPL-2.0",
"name": "GNU General Public License, Version 2.0",
"superseded_by": "GPL-3.0"
}
Return specific named properties:
{id,name}
Code
JObject result = json.Query("{id,name}");
Result:
{
"id": "GPL-2.0",
"name": "GNU General Public License, Version 2.0"
}
Return id, name and all identifiers:
{id,name,identifiers:*}
, {id,name,identifiers:**}
, {id,name,identifiers:{*}}
or {id,name,identifiers:{**}}
Because each of the identifier objects only has top level promitives, both *
and **
works the same here, if there was nested properties and we wanted the full identifier objects we either need to use **
/{**}
or query specifically for properties and child properties of the object.
Code
JObject result = json.Query("{id,name,identifiers:*}");
Result:
{
"id": "GPL-2.0",
"name": "GNU General Public License, Version 2.0",
"identifiers": [
{
"identifier": "GPL-2.0",
"scheme": "DEP5"
},
{
"identifier": "GPL-2.0",
"scheme": "SPDX"
},
{
"identifier": "License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"scheme": "Trove"
}
]
}
Return id, name and a range of identifiers:
{id,name,identifiers:[0..1]*}
, {id,name,identifiers:[0..1]**}
, {id,name,identifiers:[0..1]{*}}
or {id,name,identifiers:[0..1]{**}}
If we know a property is an array, we can add [<from>..<to>]
in front of the query on that object to select only a number of items in the array.
Both from and to are optional, where [1..]
selects elements from index 1 and up, [..1]
selects element 0 and 1 and [..]
means all and is redundant to just leaving it out.
Code
JObject result = json.Query("{id,name,identifiers:[0..1]*}");
Result:
{
"id": "GPL-2.0",
"name": "GNU General Public License, Version 2.0",
"identifiers": [
{
"identifier": "GPL-2.0",
"scheme": "DEP5"
},
{
"identifier": "GPL-2.0",
"scheme": "SPDX"
}
]
}
Return id, name and links with only the url property
{id,name,links:{url} }
Code
JObject result = json.Query("{id,name,links:{url} }");
Result:
{
"id": "GPL-2.0",
"name": "GNU General Public License, Version 2.0",
"links": [
{
"url": "https://tldrlegal.com/license/gnu-general-public-license-v2"
},
{
"url": "https://en.wikipedia.org/wiki/GNU_General_Public_License"
},
{
"url": "https://opensource.org/licenses/GPL-2.0"
}
]
}
All the above queries the objects via an extension method, when querying multiple objects its worth reusing the parsed query so it's not parsed over and over again:
Code
IStructureQuery query = StructureQL.Parse("{id,name,links:{url} }");
var result = listOfJObjects.Select(json => json.Query(query));