1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
.. _namespaces_and_bindings: Namespaces and Bindings
=======================
Namespaces and Bindings
=======================
RDFLib provides several short-cuts to working with many URIs in the same namespace.
The :mod:`rdflib.namespace` defines the :class:`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 :class:`rdflib.namespace.NamespaceManager`, e.g. using ``foaf`` for ``http://xmlns.com/foaf/0.1/``.
Each RDFLib graph has a :attr:`~rdflib.graph.Graph.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 :meth:`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 :meth:`rdflib.graph.Graph.bind` method is actually supplied by the :class:`rdflib.namespace.NamespaceManager` class - see next.
NamespaceManager
----------------
Each RDFLib graph comes with a :class:`rdflib.namespace.NamespaceManager` instance in the :attr:`~rdflib.graph.Graph.namespace_manager` field; you can use the :meth:`~rdflib.namespace.NamespaceManager.bind` method of this instance to bind a prefix to a namespace URI,
as above, however note that the :class:`~rdflib.namespace.NamespaceManager` automatically performs some bindings according to a selected strategy.
Namespace binding strategies are indicated with the ``bind_namespaces`` input parameter to :class:`~rdflib.namespace.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 :class:`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)
:class:`~rdflib.namespace.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 :meth:`~rdflib.graph.Graph.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:
.. code-block:: sparql
PREFIX : <http://xmlns.com/foaf/0.1/>
|