Search code examples
pythonrdfrdflibturtle-rdf

Namespace binding in RDFLib


In the following minimal test case:

from rdflib import Graph, Namespace, Literal, RDF

base = "http://test.com/ns"
foobar = Namespace("http://test.com/ns#")
g = Graph(base=base)
g.bind('foobar', foobar)

g.add((foobar.something, RDF.type, Literal('Blah')))
g.add((foobar.something, foobar.contains, Literal('a property')))

g.add((foobar.anotherthing, RDF.type, Literal('Blubb')))
g.add((foobar.anotherthing, foobar.contains, Literal('another property')))

print(g.serialize(format='turtle').decode("utf-8"))

I get

@base <http://test.com/ns> .
@prefix foobar: <http://test.com/ns#> .

<#anotherthing> a "Blubb" ;
    ns1:contains "another property" .

ns1:something a "Blah" ;
    ns1:contains "a property" .

what I'd expecte is more like

@base <http://test.com/ns> .
@prefix foobar: <http://test.com/ns#> .

<#anotherthing> a "Blubb" ;
    foobar:contains "another property" .

<#something> a "Blah" ;
    foobar:contains "a property" .

So either there is something I fundamentally don't understand about RDFLib and how to use namespaces, or there's something funky going on.
Any thoughts, anyone?


Solution

  • Your base declaration also needs the final has or slash in it.

    So try g = Graph(base="http://test.com/ns#") and everything will work fine

    OR

    Try without any base in this case.

    Either will give you valid results. Yes there is something odd going on deep inside RDFlib with the base, but only when it's not ended with # or /.

    By the way, your triples are a bit invalid: you can't use rdf:type with a range value of a literal, it has to be an rdf:Class instance.