XQilla Project - XSLT 2.0 and XPath 2.0 for C++

When it comes down to XML, everybody knows Java is one of the most powerful programming languages to deal with this format. The Java XML API, the documentation and the size of projects such as Xerces, Xalan and Saxon make Java an excellent option to work with XML. But then again, I'm not a Java programmer and I love C++ :P

I recently had to code a little project to simulate an automaton for a programming language. I used the FSMXML project to define the automaton, so I needed a good library to deal with XPath on C++. As I mentioned in my previous post, I discovered I needed XPath 2.0 for some queries, so on I went to find an XPath 2.0 library fo C++, since Xalan-C, as its Java counterpart, only supports version 1.0 of the specification.

I googled around and came accross XQilla which is an XQuery and XPath 2 library based on Xerces-C. It looked like something I could use for my project, so I searched a Sabayon package for that, but found none. I searched then for a Gentoo package for it, and even though I found one, there was something terribly wrong with it, which I didn't fully understand... I think it was still on testings or something, but the thing is one of the versions was hard masked and the other needed a Xerces-C version I couldn't install for some reason I don't remember. But I still wanted to try the project out, so I downloaded the sources and built the libraries successfully without problems, except for a weird --with-xerces=/usr configuration option I had to add for the configure script to find Xerces-C headers (shouldn't it default to /usr/include?). After a good amount of compile time (864 binary files outputted on the main directory) I had my working XPath 2 C++ library and I started using it by taking a look at the examples provided at the project's homepage.

After understanding the modus-operandi of this library, I started incorporating it into my program. One API design I remember I immediately questioned was regarding these lines of code:

AutoRelease<DOMXPathExpression> expressionKeywords(document->createExpression(X("language/keywords/keyword/@name"), 0));
AutoRelease<DOMXPathResult> resultKeywords(expressionKeywords->evaluate(document, DOMXPathResult::ITERATOR_RESULT_TYPE, 0));

Here, document is declared as a DOMDocument. I wondered why, if I created the expression in the first line from the document itself, I had to pass the document again as an argument to the evaluate function. A few days later I discovered an answer for that: the DOMDocument object is the only one capable of creating an expression, but what if you want to apply the expression in the context of an internal node and not the document itself? That's what the argument passed to the evaluate function indicates, as shown in these lines of code

AutoRelease<DOMXPathExpression> expressionMonoid(document->createExpression(X("n:label/n:monElmt/n:monGen/@value"), fsmxmlNamespace));
AutoRelease<DOMXPathResult> resultMonoid(expressionMonoid->evaluate(resultTransitions->getNodeValue(), DOMXPathResult::ITERATOR_RESULT_TYPE, 0));

Here, the expression created by the document object was evaluated using the resultTransitions DOMNode value as the context, which is exactly what I wanted to do.

One other trick I learned about XQilla (which may actually be regarded as a Xerces-C issue) was that it wouldn't work if your XML Schema Definition was on a remote location and you had no internet because, of course, of validation problems. To avoid this, you must disable both XercesSchema and DOMValidateIfSchema options in your parser, as shown in the following lines

parser->getDomConfig()->setParameter(XMLUni::fgDOMNamespaces, true);
parser->getDomConfig()->setParameter(XMLUni::fgXercesSchema, false);
parser->getDomConfig()->setParameter(XMLUni::fgDOMValidateIfSchema, false);

I haven't tested the XQuery capabilities of this library, but if you are going to use XSLT 2 in your C++, I can highly recommend this project.