-
Notifications
You must be signed in to change notification settings - Fork 3
RDF JSON with Optimisations
I think there could be some ways to make RDF/JSON nicer by introducing some optimisations for common cases. However I want to adhere to these principles:
- Principle of Least Variation - No optional syntax that forces users to have conditional tests in their code. There should be one way to access data of a given type.
This is the standard sample from the RDF/JSON Specification:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://example.org/about">
<dc:creator>Anna Wilder</dc:creator>
<dc:title xml:lang="en">Anna's Homepage</dc:title>
<foaf:maker rdf:nodeID="person" />
</rdf:Description>
<rdf:Description rdf:nodeID="person">
<foaf:homepage rdf:resource="http://example.org/about" />
<foaf:made rdf:resource="http://example.org/about" />
<foaf:name>Anna Wilder</foaf:name>
<foaf:firstName>Anna</foaf:firstName>
<foaf:surname>Wilder</foaf:surname>
<foaf:depiction rdf:resource="http://example.org/pic.jpg" />
<foaf:nick>wildling</foaf:nick>
<foaf:nick>wilda</foaf:nick>
<foaf:mbox_sha1sum>69e31bbcf58d432950127593e292a55975bc66fd</foaf:mbox_sha1sum>
</rdf:Description>
</rdf:RDF>
##Standard RDF/JSON
{
"http://example.org/about" : {
"http://purl.org/dc/elements/1.1/creator": [ { "value": "Anna Wilder",
"type": "literal" } ],
"http://purl.org/dc/elements/1.1/title": [ { "value": "Anna's Homepage",
"type": "literal", "lang" : "en" } ] ,
"http://xmlns.com/foaf/0.1/maker": [ { "value": "_:person",
"type" : "bnode" } ]
} ,
"_:person" : {
"http://xmlns.com/foaf/0.1/homepage": [ { "value": "http://example.org/about",
"type": "uri" } ] ,
"http://xmlns.com/foaf/0.1/made": [ { "value": "http://example.org/about",
"type": "uri" } ] ,
"http://xmlns.com/foaf/0.1/name": [ { "value": "Anna Wilder",
"type": "literal" } ] ,
"http://xmlns.com/foaf/0.1/firstName": [ { "value" : "Anna",
"type": "literal" } ] ,
"http://xmlns.com/foaf/0.1/surname": [ { "value": "Wilder",
"type": "literal" } ] ,
"http://xmlns.com/foaf/0.1/depiction": [ { "value": "http://example.org/pic.jpg",
"type": "uri" } ] ,
"http://xmlns.com/foaf/0.1/nick": [
{ "type" : "literal", "value" : "wildling"} ,
{ "type" : "literal", "value" : "wilda" }
] ,
"http://xmlns.com/foaf/0.1/mbox_sha1sum": [ { "value" : "69e31bbcf58d432950127593e292a55975bc66fd",
"type" : "literal" } ]
}
}
One optimisation could be to introduce short names for properties. However namespace mechanisms introduce variability in the choice of prefixes and/or whether to use the namespaced version of URI or the full version.
A non-variable approach is to define a fixed set of short property names that covers 90% of usage and require that these short names are always used if a property with that URI exists in the data, i.e. remove the variability.
Therefore we could have:
{
"http://example.org/about" : {
"creator": [ { "value": "Anna Wilder", "type": "literal" } ],
"title": [ { "value": "Anna's Homepage", "type": "literal", "lang" : "en" } ] ,
"maker": [ { "value": "_:person", "type" : "bnode" } ]
} ,
"_:person" : {
"homepage": [ { "value": "http://example.org/about", "type": "uri" } ] ,
"made": [ { "value": "http://example.org/about", "type": "uri" } ] ,
"name": [ { "value": "Anna Wilder", "type": "literal" } ] ,
"firstName": [ { "value" : "Anna", "type": "literal" } ] ,
"surname": [ { "value": "Wilder", "type": "literal" } ] ,
"depiction": [ { "value": "http://example.org/pic.jpg", "type": "uri" } ] ,
"nick": [ { "type": "literal", "value": "wildling"} ,
{ "type": "literal", "value": "wilda" }
] ,
"http://xmlns.com/foaf/0.1/mbox_sha1sum": [ { "value" : "69e31bbcf58d432950127593e292a55975bc66fd",
"type" : "literal" } ]
}
}
Note the last property is left as a full URI to illustrate that only the most popular properties would be special cased.
This would require every publisher and consumer to contain a lookup table:
"creator": "http://purl.org/dc/elements/1.1/creator"
"title": "http://purl.org/dc/elements/1.1/title"
"maker": "http://xmlns.com/foaf/0.1/maker"
"homepage": "http://xmlns.com/foaf/0.1/homepage"
"made": "http://xmlns.com/foaf/0.1/made"
"name": "http://xmlns.com/foaf/0.1/name"
"firstName": "http://xmlns.com/foaf/0.1/firstName"
"surname": "http://xmlns.com/foaf/0.1/surname"
"depiction": "http://xmlns.com/foaf/0.1/depiction"
This would impose a cost on publishers in particular and a lesser one on consumers who presumably only need to understand the properties that their application uses.
How would we decide which properties to special case? The easiest thing to do would be to take the most popular schemas and start there, e.g. RDF, RDFS, OWL, FOAF, SKOS, DC, GEO etc. We could create one additional schema that hoovers up additional useful properties.
This approach has one distinct strategic advantage: it helps data converge on a set of standard interoperable properties for common terms. i.e. it might prevent people creating variations of foaf:name unless they really had a strong case.
Another optimisation could be to utilise native JSON datatypes and map them to XML Schema datatypes. We can take inspiration from Turtle here too:
- Numbers with no decimal point are interpreted as xsd:integer (i.e. 5, -6, 17413, 0)
- Numbers with a decimal point are interpreted as xsd:decimal (i.e. 5.0, -0.6, 1.7413, 0.0)
- Numbers with an exponent are interpreted as xsd:double (i.e. 5e0, -12.5e10)
- True and False are interpreted as xsd:boolean
The Principle of Least Variation dictates that we can omit the "type" and "datatype" dictionary keys from our values provided we always omit them when serialising values with any of the above datatypes.
For example, this RDF/JSON could map to the following NTriples
{
"http://example.org/foo" : {
"http://example.org/p/sequence": [ { "value": 35 } ]
"http://example.org/p/speed": [ { "value": 176.4 } ]
"http://example.org/p/distance": [ { "value": "30.2e3" } ] ,
"http://example.org/p/stationary": [ { "value": true } ]
} ,
<http://example.org/foo> <http://example.org/p/sequence> "35"^^<http://www.w3.org/2001/XMLSchema#integer> .
<http://example.org/foo> <http://example.org/p/speed> "176.4"^^<http://www.w3.org/2001/XMLSchema#decimal> .
<http://example.org/foo> <http://example.org/p/distance> "30.2e3"^^<http://www.w3.org/2001/XMLSchema#double> .
<http://example.org/foo> <http://example.org/p/stationary> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> .