json-ld-api icon indicating copy to clipboard operation
json-ld-api copied to clipboard

compacting native types with a type specification in context

Open ethieblin opened this issue 2 years ago • 5 comments

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" .

playground toRDF

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

ethieblin avatar Jun 07 '22 06:06 ethieblin

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".

playground framing with fixed context

pchampin avatar Jun 07 '22 08:06 pchampin

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

ethieblin avatar Jun 07 '22 09:06 ethieblin

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.

pchampin avatar Jun 07 '22 10:06 pchampin

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.

gkellogg avatar Jun 07 '22 16:06 gkellogg

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.

Peeja avatar Jun 05 '23 16:06 Peeja