Context prefixes not loading in JsonLdParser.Load

243 Views Asked by At

I'm trying to load some basic json-ld content as a string, but I'm not able to see the namespace prefixes that should be included.

Given the following json-ld:

{
  "@context": {
    "name": "http://schema.org/name",
    "image": {
      "@id": "http://schema.org/image",
      "@type": "@id"
    },
    "foaf": "http://xmlns.com/foaf/0.1/"
  },
  "name": "Manu Sporny",
  "foaf:homepage": "http://manu.sporny.org/",
  "image": "http://manu.sporny.org/images/manu.png"
}

I run this against the dotnetrdf library:

void Main()
{   
    var targetPath = @"C:\Users\me\MinContext.json";
    var jsonStr = File.ReadAllText(targetPath);

    var parser = new JsonLdParser();
    var store = new TripleStore();
    parser.Load(store, new StringReader(jsonStr));
    
    var g = store.Graphs.FirstOrDefault();
    IUriNode rdfType = g.CreateUriNode("rdf:type");
    IUriNode home = g.CreateUriNode("foaf:homepage");
}

On the last line I get this RdfException message:

The Namespace URI for the given Prefix 'foaf' is not known by the in-scope NamespaceMapper. Did you forget to define a namespace for this prefix?

...and if you inspect the graph namespaces (g.NamespaceMap.Prefixes) you can see that it only contains three: rdf, rdfs and xsd.

So question: how do I get the foaf prefix and namespace to load correctly?

This is based on using NuGet package version 2.6.1

1

There are 1 best solutions below

3
On BEST ANSWER

Prefixes are not an inherent part of any RDF graph, they are just conventions and shortcuts so that you don't have to type the full IRI. A specific database software/implementation can have options for configuring namespaces/prefixes, but they are just for presentation.

In this case, JsonLdParser simply does not import any prefix from the source data into the graph. This is a perfectly valid behaviour, and I don't know if it can be changed. Load can also take IRdfHandlerwhich seems to be able to do something with prefixes, but creating an implementation will most likely be more difficult than simply defining the namespace yourself:

g.NamespaceMap.AddNamespace("foaf", new Uri("http://xmlns.com/foaf/0.1/"));

I'd argue this is actually the more correct option. The source document can specify foaf: to be absolutely anything, but you want this foaf: (the full meaning of a resource name comes from the IRI of its prefix, not from the prefix name itself).

The alternative to that is g.CreateUriNode(new Uri("http://xmlns.com/foaf/0.1/homepage")) which creates a completely equivalent node. Of course it is simpler to add the namespace instead of typing the full IRI every time – that's what namespaces are for.