RDFLib / rdflib

RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information.
https://rdflib.readthedocs.org
BSD 3-Clause "New" or "Revised" License
2.18k stars 560 forks source link

RDF/XML serializers cannot serialize unprefixable properties or one equal to a prefix #2409

Open kouralex opened 1 year ago

kouralex commented 1 year ago

Whilst the following works (despite the fact that the base IRI (publicID) should not be saved in prefixes)

from rdflib import Graph
g = Graph().parse(data='<a> <b> "test"@en .', publicID="http://example.org/")
g.print(format="xml")

output:

<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
   xmlns:ns1="http://example.org/"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
  <rdf:Description rdf:about="http://example.org/a">
    <ns1:b xml:lang="en">test</ns1:b>
  </rdf:Description>
</rdf:RDF>

the following does not (notice that the predicate is now simply <> but could be any unprefixable IRI outside the graph's namespaces, e.g., <http://>):

from rdflib import Graph
g = Graph().parse(data='<a> <> "test"@en .', publicID="http://example.org/")
g.print(format="xml")

Traceback:

Traceback (most recent call last):
  File "testing.py", line 7, in <module>
    g.print(format="xml")
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/graph.py", line 1370, in print
    self.serialize(None, format=format, encoding=encoding).decode(encoding),
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/graph.py", line 1340, in serialize
    serializer.serialize(stream, base=base, encoding=encoding, **args)
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/plugins/serializers/rdfxml.py", line 73, in serialize
    bindings = list(self.__bindings())
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/plugins/serializers/rdfxml.py", line 29, in __bindings
    prefix, namespace, name = nm.compute_qname_strict(predicate)
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/namespace/__init__.py", line 552, in compute_qname_strict
    prefix, namespace, name = self.compute_qname(uri, generate)
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/namespace/__init__.py", line 516, in compute_qname
    raise e
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/namespace/__init__.py", line 510, in compute_qname
    namespace, name = split_uri(uri)
  File "/home/username/.local/lib/python3.8/site-packages/rdflib/namespace/__init__.py", line 817, in split_uri
    raise ValueError("Can't split '{}'".format(uri))
ValueError: Can't split 'http://example.org/'

The same applies for both RDF/XML serializers. TTL output works as expected, though.

aucampia commented 1 year ago

Thanks for reporting this @kouralex - please consider making a PR to fix it if you can.