wu-lee
wu-lee

Reputation: 769

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

Upvotes: 1

Views: 652

Answers (1)

Gregg Kellogg
Gregg Kellogg

Reputation: 1906

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"
  ]
}

Upvotes: 2

Related Questions