json-ld-api
json-ld-api copied to clipboard
compacting native types with a type specification in context
This issue comes from https://github.com/digitalbazaar/jsonld.js/issues/466 I have the same issue when trying to round-trip from a framed JSON-LD to RDF and from the produced RDF to a framed JSON-LD.
{
"@context": {
"td": "http://example.org/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"title": {
"@id": "td:title",
"@type": "xsd:string"
},
"@language": "en"
},
"@id": "urn:something",
"title": "the title"
}
The xsd:string typing in RDF is omitted as it is considered the default type which is fine.
<urn:something> <http://example.org/title> "the title" .
When transforming the RDF data to JSON-LD again, we get
[
{
"@id": "urn:something",
"http://example.org/title": [
{
"@value": "the title"
}
]
}
]
And when trying to compact or frame back the data with the same context, we get
{
"@context": {
"td": "http://example.org/",
"xsd": "http://www.w3.org/2001/XMLSchema#",
"title": {
"@id": "td:title",
"@type": "xsd:string"
},
"@language": "en"
},
"@id": "urn:something",
"td:title": {
"@value": "the title"
}
}
playground framing with original context
It seems that the presence of "@type":"xsd:string" prevents the "title" term to be matched and framed.
The same compaction issues appears with the other native types playground xsd:boolean
First note that your context is a bit tricky:
- JSON string literals are usually interpreted as RDF literals with datatype
xsd:string
, - but you override this with a context-wide
"@language": "en"
, - but then again, you locally override that for
title
, with"@datatype": "xsd:string"
.
(you probably know that, but it took me some time to understand it, so it might benefit other rearders of this thread...).
This is why the compaction/framing algorithms have a hard time building the "best" compact form for it: it does not "detect" the interactions of these two overridings.
There is a actually a workaround: for the second override, instead of "@type": "xsd:string"
, you should use "@language": null
. Note that this is even more explicit about your intent, and this the compaction and framing algorithm are able to "understand".
Yes I agree that the context is a bit tricky (I am dealing with a defined context that people sometimes extend by adding for example a global "@language"
tag). Thank you for the "@language": null"
trick.
Regarding the xsd:boolean
(and the other native datatypes), a JSON boolean is translated into a xsd:boolean
in RDF.
playground JSON boolean to RDF
But when trying to compact it with xsd:boolean
in the context, it is not recognized. Shouldn't they match ?
playground compacting xsd:boolean
The xsd:boolean
issue is different: by default, it will not cause any round-tripping issue, because the default behavior of the fromRdf
algorithm is to produce {"@value": "true", "@type": "http://www.w3.org/2001/XMLSchema#bool" }
, and not {"@value": true}
.
Shouldn't they match ?
That's a fair question. I would be tempted to say "yes", but I am not clear about the consequences that such a change would have.
In the past, we've been reluctant to tie too closely with XSD (other than for conversion of native datatypes like number and boolean). But, this can make things confusing, and even create incorrect serializations. xsd:string
is one such case, and converting {"@value": 1.1, "@type": "xsd:decimal"}
to 1.1e0^^xsd:decimal
is wrong and not useful. Of course, caveat emptor when using native datatypes, but it seems to me that we could improve life for everyone if more aspects of JSON-LD conversion, including expansion/compaction in addition to to/from RDF, were to be more XSD aware.
This could get more complicated with formats such as YAML and CBOR which can natively express more datatypes directly, if we choose to allow extensions of the internal representation.
Just making sure I'm following: This means there's currently no way to take a JSON document (such as an API response) in which an integer value is written as a string and process it with some context (using some combination of JSON-LD 1.1 Processing Algorithms) to produce a JSON-LD document in which the value is a JSON number literal. That is, given Luke Skywalker from SWAPI (abbreviated here):
{
"name": "Luke Skywalker",
"height": "172"
}
we can't use the JSON-LD 1.1 Processing Algorithms to interpret this with some context, e.g:
{
"@vocab": "http://swapi.dev/documentation#",
"height": { "@type": "xsd:integer" }
}
to derive:
{
"@context": {
"@vocab": "http://swapi.dev/documentation#"
}
"name": "Luke Skywalker",
"height": 172
}
Rather, we can only derive the equivalent (with respect to JSON-LD):
{
"@context": {
"@vocab": "http://swapi.dev/documentation#"
}
"name": "Luke Skywalker",
"height": { "@value": "172", "@type": "xsd:integer" }
}
Do I have that right?
In my case, I'd very much like to have the native literal 172
. I can write my own code to make that happen, I just want to make sure I understand whether the Processing Algorithms are explicitly leaving that up to me.