when object keys are "data" and not predicates

Hello everyone,

Let's say I am trying to take an existing json data format and annotate it
in order to use it as json-ld.  In this format, certain objects have keys
which indicate the "name" or "label" of the value rather than corresponding
to a field or predicate.  This is very common pattern, but I don't know how
to accommodate it using json-ld:

{
  "@context": {
    "components": "http://example.com#components"
  },
  "components": {
  "foo": 1,
  "bar": 2
  }
}

By default, json-ld ignores object keys that it does not recognize, so it
would be impossible to round-trip this data through a triple store.

_:b0 <http://example.com#components> _:b1 .

My first thought is to use @index:

{
  "@context": {
    "components": {
      "@id": "http://example.com#components",
      "@container": "@index"
    }
  },
  "components": {
  "foo": 1,
  "bar": 2
  }
}

This is slightly better, but I have lost the "foo" and "bar" names in the
graph:

_:b0 <http://example.com#components> "1"^^<
http://www.w3.org/2001/XMLSchema#integer> .
_:b0 <http://example.com#components> "2"^^<
http://www.w3.org/2001/XMLSchema#integer> .

Next, I try using "@vocab":

{
  "@context": {
    "@vocab": "http://example.com/names/",
    "components":  "http://example.com#components",
    "name": "http://example.com#name",
    "value": "http://example.com#value"
  },
  "components": {
  "foo": 1,
  "bar": 2
  }
}

This manages to preserve the "foo" and "bar" names, but in the predicate
position, which is not really correct (because a "foo" in one document is
not necessarily the same as a "foo" in another document):

_:b0 <http://example.com#components> _:b1 .
_:b1 <http://example.com/names/bar> "2"^^<
http://www.w3.org/2001/XMLSchema#integer> .
_:b1 <http://example.com/names/foo> "1"^^<
http://www.w3.org/2001/XMLSchema#integer> .

If I modify the underlying json format, I can get what I actually want:

{
  "@context": {
    "components":  "http://example.com#components",
    "name": "http://example.com#name",
    "value": "http://example.com#value"
  },
  "components": [
     {"name": "foo", "value": 1},
     {"name": "bar", "value": 2}
    ]
}

Since "foo" and "bar" are names in this example, this should be indicated
by appropriate an predicate:

_:b0 <http://example.com#components> _:b1 .
_:b0 <http://example.com#components> _:b2 .
_:b1 <http://example.com#name> "bar" .
_:b1 <http://example.com#value> "2"^^<
http://www.w3.org/2001/XMLSchema#integer> .
_:b2 <http://example.com#name> "foo" .
_:b2 <http://example.com#value> "1"^^<
http://www.w3.org/2001/XMLSchema#integer> .

But what am I supposed to do if I can't change the source format of the
data?  I could do transformations on it to get the above format, but then
the json-ld markup is no longer interoperable with the original json
format, which seems self-defeating (if I need a custom tool to transform
the data, I might as well just go directly to N-triples and bypass json-ld
entirely).

What I would like is a feature like this:

{
  "@context": {
    "components": {
      "@id": "http://example.com#components",
      "@container": {
        "@container_type": "@map",
        "@key_predicate": "http://example.com#name",
        "@value_predicate": "http://example.com#value"
      }
    }
  },
  "components": {
    "foo": 1,
    "bar": 2
  }
}

A container type of "@map" would indicate that each entry in the json
object is a blank node with the desired "key" and "value" predicates mapped
to the key and value entries of the json object.  This would yield the same
graph in the previous example.

Are there other approaches to tackling this problem?  Is a solution to this
problem under consideration for future revisions of json-ld?

Thanks,
Peter

Received on Monday, 24 November 2014 13:14:40 UTC