Non-Blocking Node Set Evaluation
The most important innovation in VTD-XML's XPath implementation is its stateless, non-blocking evaluation of the node set. Unlike other XPath engines (such as JAXEN, XALAN, etc) that return the entire node set all at once, VTD-XML returns a single qualified node as soon as the XPath engine finds a match. After receiving the first match, you repeatedly call the key method in the AutoPilot class called
evalXPath(), which moves the cursor to the next node (as long as at least one matching node remains in the node set) every time it is called. To illustrate the differences between those two styles of XPath evaluation, compare the two short snippets written in JAXEN and VTD-XML respectively that execute the same application logic on the
catalog.xml in
Listing 1.
Here's the JAXEN-based code. Note that JAXEN returns the entire matching node set for the provided XPath query:
import javax.xml.parsers.*;
import java.io.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.jaxen.*;
import org.jaxen.dom.*;
import java.util.*;
public class jaxenXPath
{
public static void main(String args[]) throws Exception
{
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document d = parser.parse("catalog.xml");
XPath expression = new
org.jaxen.dom.DOMXPath("/CATALOG/CD/TITLE/text()");
// Return the entire node set all at once
List result = expression.selectNodes(d);
int sz = result.size();
for (int i=0;i<sz;i++)
{
System.out.println(" text ==> "+
((Node)result.get(i)).getNodeValue());
}
}
}
In contrast, here's the same application written for VTD-XML:
import com.ximpleware.*;
public class vtdXPath
{
public static void main(String args[]) throws Exception
{
VTDGen vg =new VTDGen();
int i;
AutoPilot ap = new AutoPilot();
ap.selectXPath("/CATALOG/CD/TITLE/text()");
if (vg.parseFile("catalog.xml", false))
{
VTDNav vn = vg.getNav();
ap.bind(vn);
//XPath eval returns one node at a time
while((i=ap.evalXPath())!=-1)
{
System.out.println(" text ==> "+
vn.toString(i));
}
ap.resetXPath();
}
}
}
In the second example above, VTD-XML's XPath implementation returns the first matching node immediately, and then returns additional matching nodes in the
while loop, letting the application begin handling matching nodes immediately, rather than waiting until the XPath implementation finds all the matching nodes.
The code sample shown above deals with only one XPath expression; to deal with multiple XPath expressions, you must instantiate multiple AutoPilot objects, each of which corresponds to a different XPath expression. When you call
selectXPath(...) multiple times, the AutoPilot object remembers only the last XPath expression. After an AutoPilot object selects an XPath expression, you call
evalXPath() which moves the embedded VTDNav instance cursor to the next available qualified node, and returns its VTD record index. When no more matching nodes remain in the node set,
evalXPath() returns
-1.