json-ldlinked-dataskos

How do I compact and/or frame a json-ld document so that IRI values are expressed succinctly as well as keys?


Given an original JSON-LD document like this example, which defines the sources for some thing1:

[
  {
  
    "@id": "https://example.com/thing1",
    "https://example.com/sources": [
      {
        "@id": "https://example.com/vocab/countries/EN"
      },
      {
        "@id": "https://example.com/vocab/countries/FR"
      }
    ]
  }
]

(I'm simplifying quite a lot - in my real use-case this is larger and generated from RDF data. ex:vocab/countries is a SKOS ConceptScheme including EN and FR as Concepts)

I want to collapse it into something approximating what I'd use to express that in more normal JSON:

{
   "@id": "https://example.com/thing1",
   "sources": ["EN", "FR"]
}

I find I can use a context to collapse into name/values and shorten the names:

{
  "@context": {
    "@version": 1.1,
    "ex": "https://example.com/",
    "sources": {
      "@id": "ex:sources",
      "@type": "@id"
    }
  },
  "@id": "ex:thing1",
  "sources": [
    "ex:vocab/countries/EN",
    "ex:vocab/countries/FR"
  ]
}

An important element is "@type": "@id" which collapses the source definitions from (a list of) objects into key/value pairs, and the enclosing context term maps https://example.com/sources to sources.

But I cannot find a way which seems to do the same on the values, so that they become EN and FR instead of ex:vocab/countries/EN and ex:vocab/countries/FR. My experiments with adding @base and @vocab properties to the context don't appear to work like I expected them to.

I also need to do this in a scoped way, so that other properties besides sources can be defined which reference different vocabularies. For instance I might want to include languages, which could include terms from a vocabulary representing English, French, Gaelic, Breton, etc. In other words, I can't just set a global vocabulary or base for the entire document.

Can anyone tell me if this kind of transform is possible, and if so, how to achieve it?

JSON-LD Playground link here


Solution

  • You could set the expected values of sources to @vocab instead of @type and use a scoped context to set the @vocab to use. For example:

    {
      "@version": 1.1,
      "ex": "https://example.com/",
      "sources": {
        "@id": "ex:sources",
        "@type": "@vocab",
        "@context": {
          "@vocab": "https://example.com/vocab/countries/"
        }
      }
    }
    

    (playground link).

    This says to treat the values of playground as vocabulary-relative IRIs, and sets the base of that vocabulary for those values. You should get the following:

    {
      "@context": {
        "@version": 1.1,
        "ex": "https://example.com/",
        "sources": {
          "@id": "ex:sources",
          "@type": "@vocab",
          "@context": {
            "@vocab": "https://example.com/vocab/countries/"
          }
        }
      },
      "@id": "ex:thing1",
      "sources": [
        "EN",
        "FR"
      ]
    }