jsonld.js icon indicating copy to clipboard operation
jsonld.js copied to clipboard

Local @context and URI Expansion, possible bug?

Open jmcanterafonseca-iota opened this issue 3 years ago • 2 comments

I have the following JSON-LD snippet:

{
    "@context": {
        "bizStep": {
            "@id": "https://example.org/bizStep",
            "@type": "@vocab",
            "@context": {
                "v1": "https://example.org/values/v1",
                "v2": "https://example.org/values/v2"
            }
        }
    },
    "bizStep": ["v1", "v2"]
}

which yields to

_:b0 <https://example.org/bizStep> <https://example.org/values/v1> .
_:b0 <https://example.org/bizStep> <https://example.org/values/v2> .

If I expand or alias bizStep into another key for instance

{
    "@context": {
        "bizStep": {
            "@id": "https://example.org/bizStep",
            "@type": "@vocab",
            "@context": {
                "v1": "https://example.org/values/v1",
                "v2": "https://example.org/values/v2"
            }
        }
    },
    "https://example.org/bizStep": ["v1", "v2"]
 }

it yields to

_:b0 <https://example.org/bizStep> "v1" .
_:b0 <https://example.org/bizStep> "v2" .

Is this a possible bug in handling local scoped LD contexts?

jmcanterafonseca-iota avatar Jan 17 '22 16:01 jmcanterafonseca-iota

Hi @jmcanterafonseca-iota!

The reason why you get different output when you use a different JSON key (e.g., "https://example.org/bizStep") is because it no longer matches the term in the context ("bizStep") using a simple string comparison. If the JSON key in the data doesn't equal the JSON key in the context (the "term"), then its term definition won't apply. So, this isn't a bug, it's just how it works; a processor only applies a term definition during expansion when a JSON key matches a term via string comparison.

If it helps, consider the case where two different terms were defined, each mapping to the same URI, but each having different term definitions. How would a term definition be selected during expansion? The spec has been written such that the author has clear control over how the data will be interpreted when it is expanded. This is made possible by keeping the processor simple: it makes no special semantic leaps to guess which term definitions to use. Rather, it simply compares JSON keys as strings. For example:

{
  "@context": {
    // this means: only if the JSON key "integer" is used, then this term definition applies
    "integer": {"@id": "example:some-uri", "@type": "http://www.w3.org/2001/XMLSchema#integer"},
    // this means: only if the JSON key "uri" is used, then this term definition applies
    "uri": {"@id": "example:some-uri", "@type": "@id"}
  },
  // this will be interpreted as a URI because this JSON key equals "uri" in "@context"
  // and the term definition says string values for this key are URIs (signaled via "@type": "@id")
  "uri": "https://test.example",
  // this will be interpreted as an integer because this JSON key equals "integer" in
  // "@context" and the term definition says string values for this key are integers
  "integer": "123",
  // this JSON key matches no JSON key in "@context", so it has no matching term definition
  // if any types are to be applied they must be done inline or via JSON types
  "example:some-uri": [
    // this will default to a string type because it's a JSON string
    "a string",
    // this will default to "http://www.w3.org/2001/XMLSchema#integer" because
    // it's a JSON number that has no decimal
    456,
    // this has an inline definition indicating it is a URI, not just a string (just because
    // it may look like URI to a human being doesn't mean the processor can or
    // will guess that, rather, it must be told)
    {"@value": "https://foo.bar", "@type": "@id"}
  ]
}

dlongley avatar Jan 17 '22 18:01 dlongley

thanks @dlongley for the detailed explanation!

jmcanterafonseca-iota avatar Jan 18 '22 07:01 jmcanterafonseca-iota