Background
We have been developing solutions for our clients lately that involve loading an ontology into a triple store, and building a UI for data entry. One of the challenges is how to handle renaming things. If you want to change the URI of a class or property in Protégé you load all the ontologies and datasets that use the old URI and use the rename entity command in the Refactor menu. Like magic, and all references to the URI are changed with the press of the Enter key. In a triple store, it is not so easy. You have to track down and change all the triples that refer to the old URI. This means writing and executing SPARQL queries using INSERT and DELETE to make changes in place. Below is an outline of how to rename a class.
Steps of Change
Let ?oldClass and ?newClass be variables bound to the URI for the old and new classes respectively – e.g. ?oldClass might
be veh:Auto and ?newClass might be veh:Car. The class rename operation involves the following steps:
- Change all instances of
?oldClassto be instances of?newClassinstead. e.g.
veh:myTeslaS rdf:type veh:Autois replaced with
veh:myTeslaS rdf:type veh:Car - Find and examine all the triples using ?
oldClassas the object. It may occur in triples where the subject is a blank node and the predicate is one of the several used for defining OWL restrictions. E.g ._:123B456x78 owl:someValuesFrom veh:Auto
Replace triples with the old class URI in the object with new triples using the new URI. Note, you might want to do the first part of the next step before doing the replace. - Find and examine all the triples using
?oldClassas the subject. It may occur in triples for declaring subclass relationships, comments as well as the triple creating the class in the first place. e.g.veh:Auto rdf:type owl:Class
Replace triples with the old class URI in the subject with new triples using the new URI. - Look around for anywhere else that the old name may be used. Possibilities include:
- If your instances use a naming convention that includes the name of the class (e.g.
veh:Auto_234)then you will have to find all the URIs that start withveh:_Autoand useveh:_Carinstead. We will look into this in a future blog. - The class name may occur in comment strings and other documentation.
- It may also be used in SPARQL queries that are programmatically called.
- If your instances use a naming convention that includes the name of the class (e.g.
Here is some SPARQL for how to do to the first step.
# Rename class veh:Auto to veh:Car
# For each ?instance of ?oldClass
# Replace the triple <?instance rdf:type ?oldClass>
# with <?instance rdf:type ?newClass>
DELETE {?instance rdf:type ?oldClass}
INSERT {?instance rdf:type ?newClass}
WHERE {BIND (veh:Auto as ?oldClass)
BIND (veh:Car as ?newClass)
?instance rdf:type ?oldClass . }
Gotchas
There are many ways to make mistakes here. Watch for the following:
- Having the
DELETEbefore theINSERTseems wrong, fear not, it is just an oddity in the SPARQL syntax. - Save out a copy of the triple store, in case things go wrong that are hard to undo. One way to do this is to make all the changes to a copy of the triple store before making them in the production one. Do all the steps, make sure things worked.
- Make sure your namespaces are defined.
- Before you make a change in place using
INSERTandDELETE, always useCONSTRUCTto see what new triples will be created. - Think about the order in which you replace triples. You can easily end up replacing triples in one step, that you needed to find the triples to replace in the next step.
- Always check the total count of triples before and after an operation that replaces triples. Generally it should be the same; track down any exceptions. The count may be less due to duplicate triples that may occur in different named graphs.
- A cautious approach would be to first insert the new triples and on a second step remove the old ones. I tried this and it did not work, it seems like a bug. Throw caution to wind, and do the delete and insert at once. You have a backup, and once you get the hang of it, the extra step will just be extra work.
- It may not be possible to fully automate changes in comments and SPARQL queries that are used programmatically. Check to see what needs to change, and what doesn’t.
What Next?
After you get step 1 working, try out steps 2 and 3 on your own, all you need to do is some straight-forward modifications to the above example. Step 4 involves more exploration and custom changes.
In an upcoming blog, we explore one of those changes. Specifically, if your naming convention for instances uses the class name in the URI then those instance URIs will have to change (e.g. from veh:_Auto_2421 to veh:_Car_2421).
