SPARQL: Updating the URI of an owl:Class in place

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:

  1. Change all instances of ?oldClass to be instances of ?newClass instead. e.g.
    veh:myTeslaS   rdf:type   veh:Auto is replaced with
    veh:myTeslaS   rdf:type   veh:Car
  2. Find and examine all the triples using ?oldClass as 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.
  3. Find and examine all the triples using ?oldClass as 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.
  4. Look around for anywhere else that the old name may be used.  Possibilities include:
    1. 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 with veh:_Auto and use veh:_Car  instead.  We will look into this in a future blog.
    2. The class name may occur in comment strings and other documentation.
    3. It may also be used in SPARQL queries that are programmatically called.

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 DELETE before the INSERT seems 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 INSERT and DELETE, always use CONSTRUCT to 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).

Read Next:
Scroll to top