How to nest rdf triples for json-ld output?

249 views
Skip to first unread message

foster...@gmail.com

unread,
Sep 28, 2015, 4:07:18 PM9/28/15
to rdflib-dev
Hello, I'm a newbie to rdflib and also to LOD in general.

I'm trying to generate the following using the rdflib-jsonld plugin.

"rdfs:label": {
"en": "mentors",
},
"owl:inverseOf": {
"rdfs:label": {
"en": "is mentored by",
}

I haven't figured out how to get the nested structure of inverseOf - label. Here's a snippet of my attempt, which didn't seem right and isn't.

ref = URIRef(some_namespace["mentor"])
store.add((ref, RDFS.label, Literal("mentors", lang="en")))
store.add((ref, RDFS.label, Literal("is mentored by", lang="en")))
store.add((ref, OWL.inverse, Literal("is mentored by")))

This gives:

"owl:inverse": "is mentored by",
"rdfs:label": [
{
"@language": "en",
"@value": "is mentored by"
},
{
"@language": "en",
"@value": "mentors"
}
]

Thanks in advance for your help!
Lynn

Niklas Lindström

unread,
Oct 1, 2015, 12:30:22 PM10/1/15
to rdfli...@googlegroups.com
Hello Lynn,

I believe this code should create the graph you need, and serialize it:

- - - 8< - - -

from rdflib import *

some_namespace = Namespace("http://example.org/ns/")

graph = Graph()

ref = URIRef(some_namespace["mentor"])
graph.add((ref, RDFS.label, Literal("mentors", lang="en")))
inverse = BNode()
graph.add((ref, OWL.inverseOf, inverse))
graph.add((inverse, RDFS.label, Literal("is mentored by", lang="en")))

output = graph.serialize(format='json-ld', context={
        'rdfs': unicode(RDFS),
        'owl': unicode(OWL),
        'rdfs:label': {'@container': '@language'}
    })
print(output)

- - - >8 - - -

Notice that I supply an explicit context, where rdfs:label is defined as using the @container: @language construct. This tells the compaction algorithm to build dictionaries for labels using their @language as keys.

The compacted output will be like:

- - - 8< - - -

{
  "@context": {
    "rdfs:label": {"@container": "@language"}
  },
  "@graph": [
    {
      "@id": "http://example.org/ns/mentor",
      "owl:inverseOf": {"@id": "_:b1"},
      "rdfs:label": {"en": "mentors"}
    },
    {
      "@id": "_:b1",
      "rdfs:label": {"en": "is mentored by"}
    }
  ]
}

- - - >8 - - -

The remaining thing to do to reach your desired form is to frame this by some means, to inline the bnode (_:b1) where it is referenced.

For basic forms you can do this manually by manipulating the resulting JSON. For this case, the following should do the trick:

- - - 8< - - -

def simplyframe(data):
    items, refs = {}, {}
    for item in data['@graph']:
        itemid = item.get('@id')
        if itemid:
            items[itemid] = item
        for vs in item.values():
            for v in [vs] if not isinstance(vs, list) else vs:
                if isinstance(v, dict):
                    refid = v.get('@id')
                    if refid and refid.startswith('_:'):
                        refs.setdefault(refid, (v, []))[1].append(item)
    for ref, subjects in refs.values():
        if len(subjects) == 1:
            ref.update(items.pop(ref['@id']))
            del ref['@id']
    data['@graph'] = items.values()

import json
data = json.loads(output)
simplyframe(data)
print json.dumps(data, indent=2)

- - - >8 - - -

Phew. :) While rdflib-jsonld does not yet do this, I might add a simple option to achieve the above (i.e. to just embed bnodes which are only referenced once). I also have a mechanism for automatic framing which achieves this (and much more) in the works. (I use it in current work, and you can see a version of it here [1].)

I hope this helps in some respect.

Cheers,
Niklas





--
http://github.com/RDFLib
---
You received this message because you are subscribed to the Google Groups "rdflib-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rdflib-dev+...@googlegroups.com.
To post to this group, send email to rdfli...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rdflib-dev/d8aa093c-ea69-477c-a959-a3851959dd8a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Lynn Foster

unread,
Oct 4, 2015, 6:53:19 PM10/4/15
to rdfli...@googlegroups.com
Niklas, Thanks so much for your very thorough help!! 
Lynn

--
http://github.com/RDFLib
---
You received this message because you are subscribed to a topic in the Google Groups "rdflib-dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rdflib-dev/U9Czox7kQL0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rdflib-dev+...@googlegroups.com.

To post to this group, send email to rdfli...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages