Peter said:
I can see how to get a list of nodes based on the name of the tag using the
method Document.getElementsByTagName. But is there anyway to get a list
based on an arbitrary XPath expression? For instance, if I wanted a list of
Nodes where an attribute was a particular value, how would I do that. In
.NET, the XmlDocument class has available the SelectNodes method. Is there
anything comparable in Java?
Java 1.5 (alias Java 1.5) has built-in XPath support on DOM nodes, see
the package javax.xml.xpath.
For instance with the XML being
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person prename="Lance" surname="Armstrong" />
<person prename="Lance" surname="Legstrong" />
</persons>
the example Java program
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
public class Test2005032601 {
public static void main (String[] args) {
try {
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document xmlDocument = docBuilder.parse(args[0]);
XPath xpathEvaluator = XPathFactory.newInstance().newXPath();
NodeList nodeList = (NodeList) xpathEvaluator.evaluate(
args[1],
xmlDocument,
XPathConstants.NODESET
);
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
System.out.println(element.getAttribute("surname"));
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
when called as
java Test2005032601 test2005032602.xml "//*[@prename = 'Lance']"
outputs
Armstrong
Legstrong
If you do not have Java 1.5 then with earlier versions you have to rely
on external packages to provide XPath evaluation, check out whether the
DOM and/or XSLT package you are using also provides an XPath API.