Skip to content

Expansion does not take property-scoped contexts for nested properties into account #380

Open
@niklasl

Description

@niklasl

There is currently a limitation in the JSON-LD 1.1 expansion algorithm which ignores property-scoped contexts for nested properties.

My specific case is:

{
  "@context": {
    "@version": 1.1,
    "@vocab": "http://purl.org/dc/terms/",
    "bibo": "http://purl.org/ontology/bibo/",
    "Print": "bibo:Book",
    "name": "http://www.w3.org/2000/01/rdf-schema#label",
    "instanceOf": "@nest",
    "contributionByRole": {
      "@id": "@nest",
      "@context": {
        "agent": "@nest",
        "aut": "creator"
      }
    },
    "provisionActivityByType": {
      "@id": "@nest",
      "@context": {
        "Publication": {
          "@id": "@nest",
          "@context": {"date": "published", "agent": "publisher"}
        }
      }
    },
    "identifiedByType": {
      "@id": "@nest",
      "@context": {
        "Isbn": {"@id": "@nest"},
        "value": "bibo:isbn"
      }
    }
  },
  "@id": "book/one",
  "@type": "Print",
  "instanceOf": {
    "contributionByRole": {
      "aut": {
        "agent": {"name": "Some Body"}
      }
    }
  },
  "identifiedByType": {
    "Isbn": {
      "value": "1234567890"
    }
  },
  "provisionActivityByType": {
    "Publication": {
      "date": "1999",
      "agent": {"name": "PubCorp"}
    }
  }
}

From which I expected to get (recompacted for brevity):

{
  "@context": {
    "@vocab": "http://purl.org/dc/terms/",
    "bibo": "http://purl.org/ontology/bibo/",
    "name": "http://www.w3.org/2000/01/rdf-schema#label"
  },
  "@id": "book/one",
  "@type": "bibo:Book",
  "bibo:isbn": "1234567890",
  "published": "1999",
  "publisher": {"name": "PubCorp"},
  "creator": {"name": "Some Body"}
}

(This is actually part of a "trick" (a "context switcheroo" if you will), whereby by compacting BibFrame data into indexed maps, and then swapping out the context with another one mapping to DC+BIBO, as per above, using nests with local contexts, the same structure is semantically differently interpreted (a kind of "poor man's inference", supporting different vocabulary granularities). The input for the above example is thus actual BibFrame data plus an idiomatic context for the shape, using indexes.)

That aside, I do believe that in general, for JSON-in-the-wild, it is quite plausible that structures mapped using nesting properties will vary the meaning of keys within each nest. As it stands, the current algorithm, somewhat arbitrarily IMHO, lacks this possibility. Nothing in the Syntax spec makes it obvious that this is so. In the test suite itself, in the example of test case in06, you could quite plausibly imagine that keys within the defined nests ("links", "attributes" and "relationships") could have different meanings but share the same name (e.g. "links" could use a "title" key with a different meaning from "title" within "attributes").

Furthermore, as far as I can tell, index keys in indexed properties can have property-scoped contexts (assuming that I interpret test case c013 correctly). To support that but not nests is rather unexpected, as they both represent not properties but "sectioned" data.

For reference, see my original question about this on the Public JSON-LD mailing list, and @gkellogg's reply, which included (and I quote):

There was no specific intention to not support this, but looking at the expansion algorithm, it brings up more considerations: for example, we don’t support @context at the top-level of nested properties either.

Nominally, to do what you want would be to duplicate step 8 (including seeing if the key expanding to @nest has an @context defined on it), and see if nesting-key has an embedded context defined, and update active context for the recursive steps; we’d also need to revert after 14.2. Similar steps would be required in the compaction algorithm. We’d also need to consider if we wanted to act on an @context member of nested value after 14.2.2, and exclude the recursive step in that case.

It would be a fairly big change, IMO, and given that we’re about to release an updated CR, probably too late to do it.

Following up on that, I wonder what would happen if step 14.2.2 is just changed from:

    <li>Recursively repeat steps <a href="#alg-expand-each-key-value">13</a>
      and <a href="#alg-expand-resolve-nest">14</a>
      using <var>nested value</var> for <var>element</var>.

to:

    <li>Recursively repeat steps
      <a href="#alg-expand-initialize-property-scoped-context">3</a>,
      <a href="#alg-expand-property-scoped-context">8</a>,
      <a href="#alg-expand-each-key-value">13</a>
      and <a href="#alg-expand-resolve-nest">14</a>
      using <code>@nest</code> as <var>active property</var>, and
      <var>nested value</var> for <var>element</var>.

Would this really require reverting, as opposed to the regular active context state handling done in the algorithm? (Assuming of course that "recursively repeat" here, as is already implicit both here and elsewhere in the algorithm, properly scopes the passed variables to each step without polluting the other steps in the loop.)

(Note that step 3 also has to be assigned id="alg-expand-initialize-property-scoped-context" in the markup if the above is added.)

(Although @gkellogg also noted that the algorithm neither supports local (explicit) contexts at the top-level of nested properties, I consider that a separate (potential) issue for which I see less motivation for. As I see it, the main reason for these features to exist ought to be to handle idiomatic JSON with zero edits, and not "native" JSON-LD. I see no practical reasons for it (I personally see little practical reason for explicit local contexts at all in 1.1, since scoped contexts are possible).)

I do believe that there is a missed opportunity here, especially considering the complexity which has been invested into nesting properties and scoped contexts. The "zero edits" goal, which much of JSON-LD 1.1 has put its force behind, warrants this to be thoroughly considered, even at this late hour, IMHO. I'll do what I can to help, if that's needed.

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Future Work

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions