Navigating/Querying EMF-Models using XPath


To make the new e4 way of building a complete model from small model pieces – named fragments – more flexible in 4.1, I’ve been developing a JXPath extension which works ontop of the reflective EMF-API.

I know that there’s already the possibility to query models using OCL but there are many more people familiar with XPath than the sometimes very cryptic OCL syntax. Some code samples might make clear why I think querying and navigating through EMF-Models using XPath is a very useful thing.

As an example model I’m using the Library-Model which is well known to most people who’ve worked with EMF.

An instance of the model would probably look like this:

The XML-Source helps probably to understand the references:

<?xml version="1.0" encoding="ASCII"?>
<extlib:Library xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:extlib="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0" xsi:schemaLocation="http:///org/eclipse/emf/examples/library/extlibrary.ecore/1.0.0 ../org.eclipse.emf.examples.library/model/extlibrary.ecore">
  <stock xsi:type="extlib:Book" borrowers="//@borrowers.1" title="Mystery Book 1" author="//@writers.0"/>
  <stock xsi:type="extlib:Book" borrowers="//@borrowers.0" title="Sience Book 1" category="ScienceFiction" author="//@writers.0"/>
  <stock xsi:type="extlib:Book" borrowers="//@borrowers.1" title="Mystery Book 2" author="//@writers.1"/>
  <stock xsi:type="extlib:Book" borrowers="//@borrowers.0" title="Sience Book 2" category="ScienceFiction" author="//@writers.1"/>
  <writers address="Hometown" firstName="Tom" lastName="Schindl" books="//@stock.0 //@stock.1"/>
  <writers address="Homecity" firstName="Boris" lastName="Bokowski" books="//@stock.2 //@stock.3"/>
  <borrowers address="Hometown" firstName="Paul" lastName="Webster" borrowed="//@stock.1 //@stock.3"/>
  <borrowers address="Homecity" firstName="Remy" lastName="Suen" borrowed="//@stock.0 //@stock.2"/>
</extlib:Library>

Now let’s try to answer some questions:

  • Find all “Mystery Books”
  • Authors of “Mystery Books”
  • Find all writers and borrowers in “Hometown”
  • Find all borrowers “Mystery books”

The XPath-Code one can use with the new support is like this.

  • Load the model and setup a context for the XPath-Query
    public class Application implements IApplication {
      public Object start(IApplicationContext context) throws Exception {
        ResourceSet resourceSet = new ResourceSetImpl();
        resourceSet.getResourceFactoryRegistry()
          .getExtensionToFactoryMap()
          .put(Resource.Factory.Registry.DEFAULT_EXTENSION,new XMIResourceFactoryImpl());
    
        URI uri = URI.createPlatformPluginURI("/testxpath/Library.xmi",true);
        Resource resource = resourceSet.getResource(uri, true);
    
        Library l = (Library) resource.getContents().get(0);
        XPathContextFactory<EObject> f = EcoreXPathContextFactory.newInstance();
        XPathContext xPathContext = f.newContext(l);
        // Execute the XPaths
      }
    }
    
  • Find all “Mystery Books”
    {
      System.out.println("Mystery Books:");
      Iterator<Book> it = xPathContext.iterate("/books[category='Mystery']");
      while( it.hasNext() ) {
        System.out.println("	" + it.next().getTitle());
      }			
    }
    
  • Authors of “Mystery Books”
    {
      System.out.println("Mystery Book Authors:");
      Iterator<Writer> it = xPathContext.iterate("/books[category='Mystery']/author");
      while( it.hasNext() ) {
        Writer w = it.next();
        System.out.println("	" + w.getFirstName() + "," + w.getLastName());
      }
    }
    
  • Find all writers and borrowers in “Hometown”
    {
      System.out.println("Borrower/Writer in Hometown:");
      Iterator<Person> it = xPathContext.iterate(
        "/borrowers[address='Hometown']|/writers[address='Hometown']"
      );
      while( it.hasNext() ) {
        Person b = it.next();
        System.out.println("	" + b.getFirstName() + "," + b.getLastName());
      }	
    }
    
  • Find all borrowers “Mystery books”
    {
      System.out.println("Borrower of Mystery books:");
      Iterator<Borrower> it = xPathContext.iterate(
        "/borrowers[borrowed/category='Mystery']");
      while( it.hasNext() ) {
        Borrower b = it.next();
        System.out.println("	" + b.getFirstName() + "," + b.getLastName());
      }
    }
    

Executing the code leads to the following output:

Mystery Books:
	Mystery Book 1
	Mystery Book 2
Mystery Book Authors:
	Tom,Schindl
	Boris,Bokowski
Borrower/Writer in Hometown:
	Paul,Webster
	Tom,Schindl
Borrower of Mystery books:
	Remy,Suen

I think the above shows how easy it is to navigate/query an EMF-Model-Instance using JXPath and using this new EMF-extension.

I hope we’ll manage to integrate this support into one of the next Eclipse 4.1 I-builds until then you can access the source from the e4-cvs-repository. I’m also thinking about moving the code at some point to EMF directly because there’s no dependency on e4 and such an implementation could be of use for others as well.

25 thoughts on “Navigating/Querying EMF-Models using XPath

  1. Hallvard Trætteberg October 8, 2010 / 7:31 am

    Nice, Tom! Two questions:
    1) Can you filter on the class of objects, e.g. [classname() = ‘SpecialBook’]
    2) There are many utilities for both the core and UI of EMF, that could/should have a home at Eclipse. But where should these be gathered (and who should decide their ‘worthyness’).

    • Tom Schindl October 8, 2010 / 10:42 am

      1) No not yet but I think one can implement custom functions and so it should easily possible
      2) I agree probably there should be an EMF project which hosts such additions

  2. Aleksander Bandelj October 8, 2010 / 10:19 am

    I’ve developed similar thing in-house, I would like to try replacing it with your implementation since it’s probably nicer and more complete. Where in Eclipse CVS is this ?

    • Tom Schindl October 8, 2010 / 10:46 am

      You can find the bundle in Eclipse CVS pserver:dev.eclipse.org:/cvsroot/eclipse/e4/org.eclipse.e4.ui/bundles/org.eclipse.e4.emf.xpath

  3. Michael Mühlberg March 22, 2011 / 9:39 am

    Hello Tom,

    are ExtendedMetaData supported?

    We have an XSD and generate Ecore from it with some renamings. In this case the ExtendedMetaData tags are filled and the XML parser/serializer is aware of these. But what about your (and other) XPath Tools?

    For me it seems reasonable to be aware of them because XPath only deals with XML and says nothing about Ecore.

    Also from an API point of view the XPath that points inside of an XML and the XML instance itself should be aligned.

    What about this?

    10x in avdance, Michael

    • Tom Schindl March 22, 2011 / 3:19 pm

      No ExtendedMetaData is not yet supported. The XPath is not executed on the XML-File but on the in memory representation of the EMF-Model. I’ll try to take a look at the ExtendedMetaData stuff to see if I can support it.

      • Jörg September 13, 2012 / 5:18 pm

        I searched a lot to find the following soltion, thus I’d like to mention it here:
        To query th XML model one can save the EMF resource and query on the returned DOMDocument. You can use the DomHelper to map the returned nodes back to EObjects.

      • Tom Schindl September 13, 2012 / 5:43 pm

        Naturallly that always works but it is much better to query the in memory model like provided by jxpath. Just fetch the projects from git.eclipse.org and you are ready to go

  4. Bob October 13, 2011 / 3:36 pm

    Is the // syntax of xpath supported? I personally tried and it blocked my application when I call iterator.hasNext()

    • Tom Schindl October 13, 2011 / 5:51 pm

      This sounds like a bug. Please provide a minimal test case so that I can take a look and debug

  5. Kris February 25, 2012 / 5:36 pm

    I am new to EMF Query / Query 2 and after browsing through the standard and OCL query tutorials in the eclipse help content, I wish that the xpath support would already be available as third option (in 3.x eclipse/emf environments). You are so right when saying that “there are many more people familiar with XPath than the sometimes very cryptic OCL syntax”. I think it would crush the learning curve for emf query immensely.

    Is there already a bug / feature request to establish xpath as third option as query syntax for emf query?

    • Tom Schindl February 27, 2012 / 8:00 am

      I don’t think there’s a bug open to include XPath to EMF Query. If you file one just add me to the CC list (tom dot schindl at bestsolution dot at)

  6. Yvonne May 21, 2012 / 8:40 pm

    Hi Tom,

    I’m a newer of EMF and XPath. I want to query point of interest from a xml file. But I failed to install JXPath with my eclipse. Is it not compatible with Mac OX? I can get XPath and XPathFactory but no XPathContext. Could you please give me some advice?

    Thank you in advance!

    Yvonne

    • Tom Schindl May 22, 2012 / 9:48 am

      First of all – the library here is not executing queries on XML-Structures but their in memory representation. I’m not sure what you mean compatible. How did you try to install JXPath?

      • Yvonne June 5, 2012 / 9:00 am

        Hi Tom,
        I’m fine with JXPath now. I directly imported JXPath in build path.
        Thank you for your help!

  7. David Rees (studgeek) September 7, 2012 / 8:30 pm

    This looks very useful. Is there a way to install and use this on Eclipse 3.6?

    • Tom Schindl September 7, 2012 / 9:28 pm

      yes – only EMF and jxpath are needed

      • David Rees (studgeek) September 8, 2012 / 2:21 am

        Sorry if this is obvious, but how do I go about installing it (and jxpath) then in 3.6? If I just need to use them as java packages where is the best place to get the jxpath-emf code? Thx.

      • Tom Schindl September 10, 2012 / 3:57 pm

        well easiest is to check them out from the git-repo (emf-support) and jxpath from orbit

  8. Daniel November 20, 2012 / 10:44 am

    Hi I would like to use the tool but I do not know how to get and install it. I am using Eclipse 4.2. Thanks in advance,

    Daniel.

  9. Daniel November 20, 2012 / 2:00 pm

    Hi Tom, I would like to use this tool for query a KDM instance meta-model. How can I get and install it?. I´m using eclipse 4.2.

    Thanks

    Daniel

  10. Felix Dorner January 22, 2013 / 10:27 am

    Hi Tom. Is this still the correct repo?

    git://git.eclipse.org/gitroot/e4/eclipse.platform.ui.e4.git

    Is an existing build for org.eclipse.e4.emf.xpath available through some p2 repo?

    • Tom Schindl January 22, 2013 / 2:26 pm

      yes the repo is still correct but IIRC it is not contained in any build.

  11. Knut Wannheden September 4, 2014 / 8:13 pm

    Nice. I just had a need for something like this again and tried to dig out an implementation of JXPath for EMF models I wrote nearly ten years ago (http://emfsearch.sourceforge.net/), but then I found yours first instead🙂 Have you meanwhile introduced a function to query an object’s EClass? I think I had something like that in my implementation.

    I think I will try to see if my implementation still works in a new Eclipse since it also featured a simple UI.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s