Using owl:Class prefix with rdflib and xml serialization
owl, python, rdf, rdflib, xml-namespaces
Solution
Instead of using the `xml` format, you need to use the `pretty-xml` format. It's listed in the documentation, Plugin serializers. That will give you the type of output that you're looking for. That is, you'd use a line like the following in order to use the PrettyXMLSerializer:
print graph.serialize(format='pretty-xml')
To address the "bonus question", you can add a line like the following to create the ontology header, and then serializing with `pretty-xml` will give you the following output.
graph.add((URIRef('https://stackoverflow.com/q/24017320/1281433/ontology.owl'), RDF.type, OWL.Ontology ))
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
>
<owl:Ontology rdf:about="https://stackoverflow.com/q/24017320/1281433/ontology.owl"/>
<owl:Class rdf:about="http://www.linkeddatatools.com/plants#planttype">
<rdfs:comment>The class of all plant types</rdfs:comment>
<rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
<rdfs:label>The plant type</rdfs:label>
</owl:Class>
</rdf:RDF>
Adding the `x rdf:type owl:Ontology` triple isn't a very OWL-centric way of declaring the ontology though. It sounds like you're looking for something more like Jena's OntModel interface (which is just a convenience layer over Jena's RDF-centric Model), or the OWLAPI, but for RDFLib. I don't know whether such a thing exists (I'm not an RDFlib user), but you might have a look at:
- RDFLib/OWL-RL: It looks like a reasoner, but it might have some of the methods that you need.
- Inspecting an ontology with RDFLib: a blog article with links to source that might do some of what you want.
- Is there a Python library to handle OWL?: A Stack Overflow question (now off-topic, because library/tool requests are off-topic, but it's an old question) where the accepted answer points out that rdflib is RDF-centric, not OWL-centric, but some of the other answers might be useful, particular this one, although most of those were outdated, even in 2011.
Problem
I would like to use the `owl:` prefix in the XML serialization of my RDF ontology (using rdflib version 4.1.1); unfortunately I'm still getting the serialization as `rdf:Description` tags. I have looked at the answer about binding the namespace to the graph at RDFLib: Namespace prefixes in XML serialization but this seems to only work when serializing using the `ns` format rather than `xml` format. Let's be more concrete. I'm attempting to get the following ontology (as taken from Introducing RDFS and OWL) in XML as follows: ``` <!-- OWL Class Definition - Plant Type --> <owl:Class rdf:about="http://www.linkeddatatools.com/plants#planttype"> <rdfs:label>The plant type</rdfs:label> <rdfs:comment>The class of all plant types.</rdfs:comment> </owl:Class> ``` Here is the python code for constructing such a thing, using `rdflib`: ``` from rdflib.namespace import OWL, RDF, RDFS from rdflib import Graph, Literal, Namespace, URIRef # Construct the linked data tools namespace LDT = Namespace("http://www.linkeddatatools.com/plants#") # Create the graph graph = Graph() # Create the node to add to the Graph Plant = URIRef(LDT["planttype"]) # Add the OWL data to the graph graph.add((Plant, RDF.type, OWL.Class)) graph.add((Plant, RDFS.subClassOf, OWL.Thing)) graph.add((Plant, RDFS.label, Literal("The plant type"))) graph.add((Plant, RDFS.comment, Literal("The class of all plant types"))) # Bind the OWL and LDT name spaces graph.bind("owl", OWL) graph.bind("ldt", LDT) print graph.serialize(format='xml') ``` Sadly, even with those bind statements, the following XML is printed: ``` <?xml version="1.0" encoding="UTF-8"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" > <rdf:Description rdf:about="http://www.linkeddatatools.com/plants#planttype"> <rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/> <rdfs:label>The plant type</rdfs:label> <rdfs:comment>The class of all plant types</rdfs:comment> <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/> </rdf:Description> </rdf:RDF> ``` Granted, this is still an Ontology, and usable - but since we have various editors, the much more compact and readable first version using the `owl` prefix would be far preferable. Is it possible to do this in `rdflib` without overriding the serialization method? Update In response to the comments, I'll rephrase my "bonus question" as simple clarification to my question at large. Not a Bonus Question The topic here involves the construction of the OWL namespace formatted ontology which is a shorthand for the more verbose RDF/XML specification. The issue here is larger though than the simple declaration of a namespace prefix for shorthand for only Classes or Properties, there are many shorthand notations that have to be dealt with in code; for example `owl:Ontology` descriptions should be added as good form to this notation. I am hoping that rdflib has support for the complete specification of the notation- rather than have to roll my own serialization.