Using owl:Class prefix with rdflib and xml serialization
Asked Answered
D

1

6

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.

Draughty answered 3/6, 2014 at 14:6 Comment(9)
I think that your "Bonus Question! A secondary question that is related is how can I add owl:Ontology headers to this RDF file?" would be better posted as a separate question. It's clear, concise, and someone who's able to answer one of these might not be able to answer the other. They should be separate questions. But an ontology header is just a few more triples, so it's not very hard to add, in terms of the RDF representation.Carty
Yeh, that's what I figured -- but it is related to the question of using the owl namespace since I'd like that header to also not be a part of the rdf:Description namespace.Draughty
It's not the same question, though. What you're looking at is an RDF/XML serialization of the RDF graph that is a translation of an OWL ontology. rdf:Description gets used in the serialization because the "type as element name" shortcut that RDF/XML permits isn't being used. These are all other serializations of the same graph (produced by Jena's rdfcat, incidentally). They're all the same RDF graph, though. Whether owl: is declared as an XML namespace is orthogonal to whether you've got an ontology header. It only differs in what it looks like.Carty
My point is that there's nothing that's "a member of the rdf:Description namespace". The rdf:Description element just means that you're writing some triples whose subject is http://www.linkeddatatools.com/plants#planttyp. The names of the subelements are the properties, and their content is the object. In RDF/XML, you can also use a value of the rdf:type property as an element name. So <owl:Class rdf:about="http://www.linkeddatatools.com/plants#planttype">…</owl:Class> is just shorthand forCarty
<rdf:Description rdf:about="http://www.linkeddatatools.com/plants#planttype"><rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/> </rdf:Description>.Carty
Thanks Joshua; I totally get that the one form is just shorthand for the other; my question is related to the construction of the shorthand using rdflib in particular. That's why I mentioned that header in particular- to show that I definitely wanted one form or the other; I will update my current question to reflect that.Draughty
By the way, do the namespace bindings work if you serialize in a different format? E.g., N3 or Turtle? I know you mentioned it in the question (I assume you meant n3, not ns), but didn't actually say whether it works in your case. Does it?Carty
Yes, the bindings do work in N3.Draughty
Aha, found it: the format for RDF/XML using some of the abbreviated forms is pretty-xml. I've added an answer.Carty
C
9

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://mcmap.net/q/1693787/-using-owl-class-prefix-with-rdflib-and-xml-serialization/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://mcmap.net/q/1693787/-using-owl-class-prefix-with-rdflib-and-xml-serialization/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.
Carty answered 4/6, 2014 at 20:12 Comment(2)
Excellent - such a simple answer too; glad you found it! I was worried I'd have to muck about with the serializer.Draughty
Nope, it'd already been mucked. Note that the prettier serializations of the RDF can be more expensive, since they have to check for the possible abbreviations. I wouldn't worry about that unless it becomes a problem, though.Carty

© 2022 - 2024 — McMap. All rights reserved.