json-ld / json-ld.org

JSON for Linked Data's documentation and playground site
https://json-ld.org/
Other
859 stars 152 forks source link

Scoped contexts with multiple instantiation AND json-ld data structures #617

Closed azaroth42 closed 6 years ago

azaroth42 commented 6 years ago

Further to #616 ...

{
  "@context": {
    "@version": 1.1,
    "eg": "https://example.com/ns/",
    "label": {"@id": "eg:label3", "@container": "@set"},
    "Type1": {"@id": "eg:Type1", "@context": {"label": {"@id": "eg:label1", "@type": "xsd:string"}}},
    "Type2": {"@id": "eg:Type2", "@context": {"label": {"@id": "eg:label2", "@container": "@language"}}},
    "Type3": "eg:Type3"
  },
  "@id": "https://example.com/object/1",
  "@type": ["Type1", "Type2", "Type3"],
  "label": "1 or 2... OR 3??? Place bets now!"
}

Now what is the expected behavior for expanding label ?

The data does not match the scoped definition in Type2, as it's not a language map, nor the top level label as it's not an array. The data is valid according to the definition of Type1 however, as the value is a string.

Currently the playground, and thus I anticipate the spec, still says that it's eg:label2 despite the mapping for label2 not conforming.

iherman commented 6 years ago

Isn't this fundamentally the same as #616 (just more convoluted)? The evaluation takes the order into account (why does the spec result in label2 and not label1?) to resolve ambiguities, but there should be a warning in the document and maybe in the processor that user should avoid doing that because it may goes against the triple representation and its round-tripping.

azaroth42 commented 6 years ago

I think it's more than #616, as the JSON structure is incorrect for the selected predicate. label2 is defined as a language map, and the label in the data is not a language map ... so how can it legitimately be label2? I think it should be an error state for the data?

gkellogg commented 6 years ago

This would be pretty much the same as if you had the following JSON-LD:

{
  "@context": [{
    "@version": 1.1,
    "eg": "https://example.com/ns/",
    "label": {"@id": "eg:label3", "@container": "@set"},
    "Type1": {"@id": "eg:Type1"},
    "Type2": {"@id": "eg:Type2"},
    "Type3": "eg:Type3"
    },  {
      "label": {"@id": "eg:label1", "@type": "xsd:string"}
    }, {
      "label": {"@id": "eg:label2", "@container": "@language"}
    }]
  },
  "@id": "https://example.com/object/1",
  "@type": ["Type1", "Type2", "Type3"],
  "label": "1 or 2... OR 3??? Place bets now!"
}

The active context is formed by merging each of the entries in @context in turn, so in the end, there is a single term definition for label: {"@id": "eg:label2", "@container": "@language"}, as each definition for label replaces the previous definition. eg:label1 won't be used, as there is no term definition that includes it.

The bit where scoped contexts are replaced comes if you have a term with a scoped context which is replaced by the same term containing a different scoped context, which doesn't happen in this case.

There is no mechanism that would have multiple term definitions for the same term which would be selected based on best match. That only happens when compacting, and there are multiple different terms with the same @id which have different properties that can be used in term selection.

azaroth42 commented 6 years ago

Okay, closing.