gjhiggins/rdflib — Issue #151: Namespaces beginning with _ are invalid
Author: gjhiggins
Created: 2011-10-19 01:31:14+00:00
State: open

Originally filed by wwai...@gmail.com on 2010-11-26T22:53:44

The NamespaceManager will invent namespace prefixes when its
compute_qname method is called. The prefixes it invents start with
an underscore. The legality of this might be debated but there are
several parsers, amongst them redland, that cannot read N3/turtle
generated by rdflib because of this unless inordinate care is taken
that all possible prefixes be defined beforehand.

The fix below copies the behaviour of Virtuoso which invents prefixes
starting with "ns" and a number.

Patch below

---

diff --git a/rdflib/namespace.py b/rdflib/namespace.py
index 935f1a1..127a854 100644
--- a/rdflib/namespace.py
+++ b/rdflib/namespace.py
@@ -191,7 +191,12 @@ class NamespaceManager(object):
namespace = URIRef(namespace)
prefix = self.store.prefix(namespace)
if prefix is None:
- prefix = "_%s" % len(list(self.store.namespaces()))
+ num = 1
+ while 1:
+ prefix = "ns%s" % num
+ if not self.store.namespace(prefix):
+ break
+ num += 1
self.bind(prefix, namespace)
self.__cache[uri] = (prefix, namespace, name)
return self.__cache[uri]
diff --git a/test/test_namespace.py b/test/test_namespace.py
new file mode 100644
index 0000000..4aba036
--- /dev/null
+++ b/test/test_namespace.py
@@ -0,0 +1,17 @@
+from rdflib.graph import Graph
+from rdflib.term import URIRef
+
+def test_qname():
+ """Test sequential assignment of unknown prefixes"""
+ g = Graph()
+ assert g.compute_qname(URIRef("http://foo/bar/baz")) == \
+ ("ns1", URIRef("http://foo/bar/"), "baz")
+
+ assert g.compute_qname(URIRef("http://foo/bar#baz")) == \
+ ("ns2", URIRef("http://foo/bar#"), "baz")
+
+ # should skip this because we already assign it
+ g.bind("ns3", URIRef("http://exampe.org/"))
+
+ assert g.compute_qname(URIRef("http://blip/blop")) == \
+ ("ns4", URIRef("http://blip/"), "blop")