digitalbazaar / jsonld.js

A JSON-LD Processor and API implementation in JavaScript
https://json-ld.org/
Other
1.66k stars 195 forks source link

Bug in scoped contexts #409

Open jakubklimek opened 4 years ago

jakubklimek commented 4 years ago

There is probably a bug in handling scoped contexts. This is the same as https://github.com/json-ld/json-ld.org/issues/734 In the snippet below, začátek and konec (beginning and end in Czech) have equivalent contexts. However, when used in data, they behave differently. Namely the context in konec is ignored, while when začátek is used, the context is applied. When the začátek definition is removed from the context, konec starts working. This can be tested in json-ld playground.

{
    "@context": {
        "typ": "@type",
        "time": "http://www.w3.org/2006/time#",
        "Časový interval": {
            "@id": "time:ProperInterval",
            "@context": {
                "začátek": {
                    "@id": "time:hasBeginning",
                    "@context": {
                        "time": "http://www.w3.org/2006/time#",
                        "xsd": "http://www.w3.org/2001/XMLSchema#",
                        "časy": "https://slovník.gov.cz/generický/čas/pojem/",
                        "Časový okamžik": {
                            "@id": "time:Instant",
                            "@context": {
                                "datum": {
                                    "@id": "time:inXSDDate",
                                    "@type": "xsd:date"
                                },
                                "datum_a_čas": {
                                    "@id": "time:inXSDDateTimeStamp",
                                    "@type": "xsd:dateTimeStamp"
                                },
                                "nespecifikovaný": {
                                    "@id": "časy:je-nespecifikovaný",
                                    "@type": "xsd:boolean"
                                }
                            }
                        }
                    }

                },
                "konec": {
                    "@id": "time:hasEnd",
                    "@context": {
                        "time": "http://www.w3.org/2006/time#",
                        "xsd": "http://www.w3.org/2001/XMLSchema#",
                        "časy": "https://slovník.gov.cz/generický/čas/pojem/",
                        "Časový okamžik": {
                            "@id": "time:Instant",
                            "@context": {
                                "datum": {
                                    "@id": "time:inXSDDate",
                                    "@type": "xsd:date"
                                },
                                "datum_a_čas": {
                                    "@id": "time:inXSDDateTimeStamp",
                                    "@type": "xsd:dateTimeStamp"
                                },
                                "nespecifikovaný": {
                                    "@id": "časy:je-nespecifikovaný",
                                    "@type": "xsd:boolean"
                                }
                            }
                        }
                    }

                }
            }
        }
    },
    "typ": "Časový interval",
    "konec": {
        "typ": "Časový okamžik",
        "datum_a_čas": "2019-01-14T09:30:00+02:00"
    }
}
RinkeHoekstra commented 3 years ago

I have a similar issue with scoped contexts and IRI expansion using scoped @base or @vocab definitions. Only the first scope context is used, the other is ignored. Adding this here, and linking to https://github.com/json-ld/json-ld.org/issues/734 .

To test: two examples. One using @base and one using @vocab:

Using @base

{
  "@context": {
    "@base": "http://example.com/entity/test/",
    "@vocab": "http://example.com/schema/test/",
    "b": {
      "@context": {
        "@base": "http://example.com/test/"
      },
      "@type": "@id"
    },
    "a": {
      "@context": {
        "@base": "http://example.com/test/"
      },
      "@type": "@id"
    }
  },
  "@id": "justATest",
  "b": "1234",
  "a": "5678"
}

This should give

Subject Predicate Object
http://example.com/entity/test/justATest http://example.com/schema/test/b http://example.com/test/1234
http://example.com/entity/test/justATest http://example.com/schema/test/a http://example.com/test/5678

But instead gives

Subject Predicate Object
http://example.com/entity/test/justATest http://example.com/schema/test/b http://example.com/test/1234
http://example.com/entity/test/justATest http://example.com/schema/test/a 5678

Using @vocab

Different context, now using the @vocab mechanism... same results:

{
  "@context": {
    "@base": "http://example.com/entity/test/",
    "@vocab": "http://example.com/schema/test/",
    "b": {
      "@context": {
        "@vocab": "http://example.com/test/"
      },
      "@type": "@vocab"
    },
    "a": {
      "@context": {
        "@vocab": "http://example.com/test/"
      },
      "@type": "@vocab"
    }
  },
  "@id": "justATest",
  "b": "1234",
  "a": "5678"
}

Results:

Subject Predicate Object
http://example.com/entity/test/justATest http://example.com/schema/test/a 5678
http://example.com/entity/test/justATest http://example.com/schema/test/b http://example.com/test/1234

Change the order in the @context

Just including the example from the @base method... This context defines a first, and then b. Now the effect is the other way around. The value for a is properly expanded, and the one for b isn't.

{
  "@context": {
    "@base": "http://example.com/entity/test/",
    "@vocab": "http://example.com/schema/test/",
    "a": {
      "@context": {
        "@base": "http://example.com/test/"
      },
      "@type": "@id"
    },
    "b": {
      "@context": {
        "@base": "http://example.com/test/"
      },
      "@type": "@id"
    }
  },
  "@id": "justATest",
  "b": "1234",
  "a": "5678"
}

Results:

Subject Predicate Object
http://example.com/entity/test/justATest http://example.com/schema/test/a http://example.com/test/5678
http://example.com/entity/test/justATest http://example.com/schema/test/b 1234