pythonrdflib

#rdflib (python): how to get a URIRef from a string such as 'ns:xxx'?


I have a RDFlib graph g, whose NameSpaceManager is aware of some namespaces.

How do I get a URIRef from a string such as 'ns:xxx', where ns is the prefix associated to a namespace known by g.namespace_manager? Basically, I'm looking for a method which does the inverse operation of URIRef's n3(g.namespace_manager). I'm pretty confident that there is a way to do it, as a similar function is needed to parse turtle files, or sparql queries, but I can't find it. Otherwise of course, it must not be very difficult to write it.

TIA


Solution

  • from rdflib import Graph, Namespace
    from rdflib.namespace import RDF
    
    g = Graph()
    NS = Namespace("http://example.com/")
    
    # then, say Xxx is a class and Aaa is an instance of Xxx...
    g.add((NS.Aaa, RDF.type, NS.Xxx))
    
    # so use NS.Xxx (or NS["Xxx"]) to get a URIRef of NS.Xxx from Namespace NS
    print(type(NS))     # --> <class 'rdflib.term.URIRef'>
    print(type(NS.Xxx)) # --> <class 'rdflib.term.URIRef'>
    print(NS.Xxx)       # --> "http://example.com/Xxx"
    

    If you want to bind a prefix within a graph, you use the rdflib Graph class' bind() method so, for the code above, you would use:

    g.bind("ns", NS)
    

    Now the graph, if serialized with a format that knows about prefixes, like Turtle, will use "ns". The above data would be:

    @prefix ns: <http://example.com/> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    
    ns:Aaa rdf:type ns:Xxx .
    

    So, in Python, if you want to make the URI "http://example.com/Xxx"" from the string "ns:Xxx" you should have everything you need:

    IFF, on the other hand, you didn't declare the namespace yourself but it's in a graph and you only have the short form URI "ns:Xxx", you can do this to list all bound prefixes & namespaces used in the graph:

    for n in g.namespace_manager.namespaces():
        print(n)
    

    returns, for the data above:

    ('xml', rdflib.term.URIRef('http://www.w3.org/XML/1998/namespace'))
    ('rdf', rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#'))
    ('rdfs', rdflib.term.URIRef('http://www.w3.org/2000/01/rdf-schema#'))
    ('xsd', rdflib.term.URIRef('http://www.w3.org/2001/XMLSchema#'))
    ('eg', rdflib.term.URIRef('http://example.com/'))
    

    So, if you know "eg:Xxx", you can split off the "eg" part and make the URI you want like this:

    print(
        [str(x[1]) for x in g.namespace_manager.namespaces() if x[0] == s.split(":")[0]]
        [0] + s.split(":")[1]
    )
    

    prints:

    http://example.com/Xxx