Namespaces and Bindings¶
RDFLib provides several short-cuts to working with many URIs in the same namespace.
The rdflib.namespace
defines the rdflib.namespace.Namespace
class which lets you easily create URIs in a namespace:
from rdflib import Namespace
EX = Namespace("http://example.org/")
EX.Person # a Python attribute for EX. This example is equivalent to rdflib.term.URIRef("http://example.org/Person")
# use dict notation for things that are not valid Python identifiers, e.g.:
n['first%20name'] # as rdflib.term.URIRef("http://example.org/first%20name")
These two styles of namespace creation - object attribute and dict - are equivalent and are made available just to allow for valid
RDF namespaces and URIs that are not valid Python identifiers. This isn’t just for syntactic things like spaces, as per
the example of first%20name
above, but also for Python reserved words like class
or while
, so for the URI
http://example.org/class
, create it with EX['class']
, not EX.class
.
Common Namespaces¶
The namespace
module defines many common namespaces such as RDF, RDFS, OWL, FOAF, SKOS, PROF, etc. The list of the
namespaces provided grows with user contributions to RDFLib.
These Namespaces, and any others that users define, can also be associated with prefixes using the rdflib.namespace.NamespaceManager
, e.g. using foaf
for http://xmlns.com/foaf/0.1/
.
Each RDFLib graph has a namespace_manager
that keeps a list of namespace to prefix mappings. The namespace manager is populated when reading in RDF, and these prefixes are used when serialising RDF, or when parsing SPARQL queries. Prefixes can be bound with the rdflib.graph.Graph.bind()
method:
from rdflib import Graph, Namespace
from rdflib.namespace import FOAF
EX = Namespace("http://example.org/")
g = Graph()
g.bind("foaf", FOAF) # bind an RDFLib-provided namespace to a prefix
g.bind("ex", EX) # bind a user-declared namespace to a prefix
The rdflib.graph.Graph.bind()
method is actually supplied by the rdflib.namespace.NamespaceManager
class - see next.
NamespaceManager¶
Each RDFLib graph comes with a rdflib.namespace.NamespaceManager
instance in the namespace_manager
field; you can use the bind()
method of this instance to bind a prefix to a namespace URI,
as above, however note that the NamespaceManager
automatically performs some bindings according to a selected strategy.
Namespace binding strategies are indicated with the bind_namespaces
input parameter to NamespaceManager
instances
and may be set via Graph
also:
from rdflib import Graph
from rdflib.namespace import NamespaceManager
g = Graph(bind_namespaces="rdflib") # bind via Graph
g2 = Graph()
nm = NamespaceManager(g2, bind_namespaces="rdflib") # bind via NamespaceManager
Valid strategies are:
- core:
binds several core RDF prefixes only
owl, rdf, rdfs, xsd, xml from the NAMESPACE_PREFIXES_CORE object
this is default
- rdflib:
binds all the namespaces shipped with RDFLib as DefinedNamespace instances
all the core namespaces and all the following: brick, csvw, dc, dcat
dcmitype, dcterms, dcam, doap, foaf, geo, odrl, org, prof, prov, qb, sdo
sh, skos, sosa, ssn, time, vann, void
see the NAMESPACE_PREFIXES_RDFLIB object in
rdflib.namespace
for up-to-date list
- none:
binds no namespaces to prefixes
note this is NOT default behaviour
- cc:
using prefix bindings from prefix.cc which is a online prefixes database
not implemented yet - this is aspirational
Re-binding¶
Note that regardless of the strategy employed, prefixes for namespaces can be overwritten with users preferred prefixes, for example:
from rdflib import Graph
from rdflib.namespace import GEO # imports GeoSPARQL's namespace
g = Graph(bind_namespaces="rdflib") # binds GeoSPARQL's namespace to prefix 'geo'
g.bind('geosp', GEO, override=True)
NamespaceManager
also has a method to normalize a given url:
from rdflib.namespace import NamespaceManager
nm = NamespaceManager(Graph())
nm.normalizeUri(t)
For simple output, or simple serialisation, you often want a nice
readable representation of a term. All RDFLib terms have a
.n3()
method, which will return a suitable N3 format and into which you can supply a NamespaceManager instance
to provide prefixes, i.e. .n3(namespace_manager=some_nm)
:
>>> from rdflib import Graph, URIRef, Literal, BNode
>>> from rdflib.namespace import FOAF, NamespaceManager
>>> person = URIRef("http://xmlns.com/foaf/0.1/Person")
>>> person.n3()
'<http://xmlns.com/foaf/0.1/Person>'
>>> g = Graph()
>>> g.bind("foaf", FOAF)
>>> person.n3(g.namespace_manager)
'foaf:Person'
>>> l = Literal(2)
>>> l.n3()
'"2"^^<http://www.w3.org/2001/XMLSchema#integer>'
>>> l.n3(NamespaceManager(Graph(), bind_namespaces="core"))
'"2"^^xsd:integer'
The namespace manage also has a useful method compute_qname
g.namespace_manager.compute_qname(x)
(or just g.compute_qname(x)
) which takes a URI and decomposes it into the parts:
self.assertEqual(g.compute_qname(URIRef("http://foo/bar#baz")),
("ns2", URIRef("http://foo/bar#"), "baz"))
Namespaces in SPARQL Queries¶
The initNs
argument supplied to query()
is a dictionary of namespaces to be expanded in the query string.
If you pass no initNs
argument, the namespaces registered with the graphs namespace_manager are used:
from rdflib.namespace import FOAF
graph.query('SELECT * WHERE { ?p a foaf:Person }', initNs={'foaf': FOAF})
In order to use an empty prefix (e.g. ?a :knows ?b
), use a PREFIX
directive with no prefix in the SPARQL query to set a default namespace:
PREFIX : <http://xmlns.com/foaf/0.1/>