Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No standard way to map a JSON predicate to a URI #29

Open
dbooth-boston opened this issue Dec 7, 2018 · 6 comments
Open

No standard way to map a JSON predicate to a URI #29

dbooth-boston opened this issue Dec 7, 2018 · 6 comments
Labels
Category: related standards For RDF-related standards standards Standardization should address this

Comments

@dbooth-boston
Copy link
Collaborator

"there is a wide proliferation of JSON on the web. Yet (in 2019!) we do not have a standard way for developers, and automated tools, to map a JSON predicate into a URI. I've suggested in the past : foo -> urn:string:foo . But that has yet to gain mind share. Tim has suggested we have an HTTP JSON
ontology."
https://lists.w3.org/Archives/Public/semantic-web/2018Nov/0171.html

@dbooth-boston dbooth-boston added the Category: related standards For RDF-related standards label Dec 8, 2018
@VladimirAlexiev
Copy link

Whaddayamean? What are JSONLD contexts for? cc @manusporny

@dbooth-boston dbooth-boston added standards Standardization should address this and removed standards Standardization should address this labels Mar 11, 2019
@BigBlueHat
Copy link
Member

Yeah, this is exactly what JSON-LD contexts are for. 😄

The original thread goes on to include this bit of explanation of intent:

This is more a question of : what would the longer form be, if you were,
say, writing an automated tool to create a context.

Think the idea was to attempt a "standard" mapping for JSON terms...but that would rather limit the world of open data--i.e. putting all keys into a urn:string: prefix globally would assume universal meaning of those keys...which would be wrong.

The simplest way to do this in JSON-LD (though obviously not the most resilient...or even wisest...) would be this:

{
  "@context": {
    "@vocab": "urn:{personal-or-app-namespace}:"
  },
  "foo": "bar",
  "baz": {
    "foo": "..."
  }
}

becomes...

_:b0 <urn:{personal-or-app-namespace}:baz> _:b1 .
_:b0 <urn:{personal-or-app-namespace}:foo> "bar" .
_:b1 <urn:{personal-or-app-namespace}:foo> "..." .

Or add a proper @id to avoid all those blank nodes:

{
  "@context": {
    "@vocab": "urn:{personal-or-app-namespace}:"
  },
  "@id": "http://example.com/#local-json",
  "foo": "bar",
  "baz": {
    "foo": "..."
  }
}

becomes...

<http://example.com/#local-json> <urn:{personal-or-app-namespace}:baz> _:b0 .
<http://example.com/#local-json> <urn:{personal-or-app-namespace}:foo> "bar" .
_:b0 <urn:{personal-or-app-namespace}:foo> "..." .

Regardless, this is certainly a solved problem, afaict.

@dbooth-boston
Copy link
Collaborator Author

That's an interesting point, but I don't think it fully solves the problem, because nested predicates having the same name need to map to different URIs, to avoid information loss. In JSON, you can distinguish them by the nesting context, in the tree structure. But that context is lost if you just use a generic @vocab in JSON-LD. For example, this (view in playground):

{
  "@context": {
    "@vocab": "urn:TEST:"
  },
  "@id": "http://example.com/#local-json",
  "foo": "bar",
  "baz": {
    "foo": "..."
  }
}

becomes this in RDF:

<http://example.com/#local-json> <urn:TEST:foo> "bar" .
<http://example.com/#local-json> <urn:TEST:baz> _:b0 .
_:b0 <urn:TEST:foo> "..." .

Note that both the outer and inner instances of JSON property "foo" became urn:TEST:foo.

What we need instead is for those instances to map to different URIs, something like this:

<http://example.com/#local-json> <urn:TEST:baz> _:b0 .
<http://example.com/#local-json> <urn:TEST:foo> "bar" .
_:b0 <urn:TEST:baz/foo> "..." .

This can be done in JSON-LD 1.1 (but not 1.0) using a nested @context (view in playground):

{
  "@context": {
    "@vocab": "urn:TEST:"
  },
  "@id": "http://example.com/#local-json",
  "foo": "bar",
  "baz": {
    "@context": {
      "@vocab": "baz/"
  },
    "foo": "..."
  }
}

But AFAIK that would require modifying the JSON, to insert those nested @context statements.

@gkellogg, is that correct, or is there some other way of achieving unique URIs for nested properties that have the same name, without modifying the JSON?

@gkellogg
Copy link
Member

See Scoped Contexts which is there specifically for cases like this.

playground link

{
  "@context": {
    "@vocab": "urn:TEST:",
    "baz": {"@context": {"@vocab": "baz/"}}
  },
  "@id": "http://example.com/#local-json",
  "foo": "bar",
  "baz": {
    "foo": "..."
  }
}

@dbooth-boston
Copy link
Collaborator Author

Nice! That does have the minor limitation that it still requires the JSON document to be analyzed in advance -- or its schema already known -- in order to emit a custom @context containing all of those nested @vocab definitions. But that would be very straightforward to automate with a standard tool that could take any JSON input and produce the corresponding @context.

@BigBlueHat
Copy link
Member

Additionally, contexts can be provided separately from the JSON either via an HTTP Link header (if you control the server responses or proxy them, but not the data): https://www.w3.org/TR/json-ld/#interpreting-json-as-json-ld

Or, via any JSON-LD API compliant code's expandContext option:

The JSON-LD 1.1 Processing Algorithms and API specification [JSON-LD11-API] provides for an expandContext option for specifying a context to use when expanding JSON documents programmatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: related standards For RDF-related standards standards Standardization should address this
Projects
None yet
Development

No branches or pull requests

4 participants