json-ld / json-ld.org

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

compactIri doesn't work when there are 2 different uris with the same shortname #772

Closed garpinc closed 2 years ago

garpinc commented 2 years ago

String compactIri(String iri, Object value, boolean relativeToVocab, boolean reverse) {

calls: if (relativeToVocab && getInverse().containsKey(iri)) {

I have 2 different uris which map to the same short name but it seems the inverse function throws away the relationship of one of the uris.

My json that it was compacting has one context at the top of the json with all contexts of the types in the file.

I can imagine that if you receive json with the same short name in 2 different types that it would have to scope the right context at the level of the type in order to get the right expanded url but in my case I don't need to worry about this because I'm not trying to do the expansion since it's already expanded directly from rdf. I already have the uris and I just want the right short name but the way the code is written doesn't seem to allow that.

Please advise

pchampin commented 2 years ago

@garpinc could you please provide a minimal example showing your problem, as;

Did you test it with different implementations? This would help determining whether this is an issue with the spec, or an implementation bug.

gkellogg commented 2 years ago

The short name/compact IRI/relative IRI/term associated with an IRI is dependent on the context that is in force. There is no absolutely "right" short name to use outside of this. The JSON-LD Compaction algorithm, in turn depends on the IRI Compaction Algorithm which considers the active context as well as the value to be compacted, in order to chose among several possible terms to represent the property IRI. For example, within a single context, I might define two terms that expand to the same IRI (link):

{
  "@context": {
    "obj": {"@id": "http://example.com/#iri", "@type": "@id"},
    "lit": {"@id": "http://example.com/#iri", "@language": "en"}
  },
  "obj": "http://example.com/#obj",
  "lit": "Literal"
}

Both "obj" and "lit" are terms expanding to http://example.com/#iri, but when compacting, the term to choose will depend on the one who's value best matches the term definitions.

The Term Selection Algorithm goes into more detail on how this is done.

Of course, scoped contexts can also come into play here.