Skip to content

Instantly share code, notes, and snippets.

@niklasl
Created May 22, 2012 16:41
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save niklasl/2770154 to your computer and use it in GitHub Desktop.
Save niklasl/2770154 to your computer and use it in GitHub Desktop.
Generating a JSON-LD context from an RDF vocabulary
import sys
from rdflib import *
fpath = sys.argv[1]
prefix = sys.argv[2]
g = Graph().parse(fpath, format='n3' if fpath.endswith(('.n3', '.ttl')) else 'xml')
def name_pair(item):
qname = item.qname()
term = qname.split(':')[-1]
if qname == term:
qname = "%s:%s" % (prefix, term)
return term, qname
for pfx, iri in g.namespaces():
globals().setdefault(pfx.upper(), Namespace(iri))
PROTEGE = Namespace("http://protege.stanford.edu/plugins/owl/protege#")
classes, multiprops, singleprops = set(), set(), set()
ranges = {}
for r in sorted(set(g.resource(s) for s in g.subjects() if isinstance(s, URIRef))):
if r.value(PROTEGE['abstract']):
continue
types = set(o.identifier for o in r.objects(RDF.type))
range_type = r.value(RDFS.range)
range_iri = range_type and range_type.identifier
one = any(True for restr in r.subjects(OWL.onProperty)
if restr.value(OWL.cardinality) == 1 or
restr.value(OWL.maxCardinality) == 1)
if types & {RDFS.Class, OWL.Class}:
classes.add(r)
elif range_iri and range_iri.startswith(XSD) or range_iri == RDFS.Literal:
ranges.setdefault(range_type.qname(), set()).add(r)
elif OWL.DatatypeProperty in types:
ranges.setdefault("rdfs:Literal", set()).add(r)
elif one or types & {RDF.Property, OWL.FunctionalProperty}:
singleprops.add(r)
elif OWL.ObjectProperty in types:
multiprops.add(r)
print ' {'
for item in sorted(classes):
print ' "%s": "%s",' % name_pair(item)
print ' }, {'
for item in sorted(multiprops):
print ' "%s": {"@id": "%s", "@container": "@set"},' % name_pair(item)
print ' }, {'
for dtype in sorted(ranges):
for item in sorted(ranges[dtype]):
if dtype == "rdfs:Literal":
print ' "%s": {"@id": "%s", "@language": null},' % (name_pair(item))
else:
print ' "%s": {"@id": "%s", "@type": "%s"},' % (name_pair(item) + (dtype,))
print ' }, {'
for item in sorted(singleprops):
print ' "%s": "%s",' % name_pair(item)
print ' }'
@acka47
Copy link

acka47 commented Nov 8, 2013

Hello @niklasl . I would like to make an JSON-LD context out of the GND ontology (rdf/xml) and tried to use this script. Unfortunately it didn't work.

Running python rdf_vocab_to_jsonld_context.py gnd.ttl gnd gives back the following:

Traceback (most recent call last):
  File "rdf-vocab2contecxt.py", line 24, in <module>
    for r in sorted(set(g.resource(s) for s in g.subjects() if isinstance(s, URIRef))):
  File "rdf-vocab2contecxt.py", line 24, in <genexpr>
    for r in sorted(set(g.resource(s) for s in g.subjects() if isinstance(s, URIRef))):
AttributeError: 'Graph' object has no attribute 'resource'

I am not familiar with python or any other programming language. Maybe this is an easy fix so that you can help me with that. I definitely don't want to create the JSON-LD context document manually...

@niklasl
Copy link
Author

niklasl commented Nov 8, 2013

Hello! Is it possible for you to update RDFLib on your machine? Graph.resource was added in RDFLib 3.2 (the latest release is 4.0.1).

@acka47
Copy link

acka47 commented Nov 11, 2013

With some help from @dr0i, I upgraded to RDFLib 32. and the script ran. Will have to do some manual cleanup, though. But it is much better than doing everything manually. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment