package ca.umontreal.iro.rali; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactoryConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * Encapsulates the compilation and matching of an XPath expression * Deals internally with exceptions that can be raised at compilation and evaluation */ public class XPath { private XPathExpression xpexpr; private String expr; private static String xPathProvider; // compile the xpath expression /** * Compile the XPath expression * @param expr String containing the XPath expression to compile * @param context Namespace context of the expression * @throws XPathFactoryConfigurationException */ XPath(String expr,NamespaceContext context) throws XPathFactoryConfigurationException{ try { this.expr=expr; XPathFactory xpathF=XPathFactory.newInstance(XPathConstants.DOM_OBJECT_MODEL); javax.xml.xpath.XPath xpath=xpathF.newXPath(); xPathProvider=xpath.getClass().getName(); xpath.setNamespaceContext(context); xpexpr = xpath.compile(expr); } catch (XPathExpressionException e) { System.err.println("Invalid XPath expression:"+expr); System.err.println(e.getCause().getMessage()); System.exit(1); } } public String toString(){ return "MXP{"+expr+"}"; } /** * Return the name of the XPath processor * @return string giving the name */ public static String getXPathProvider(){ return xPathProvider; } /** * Check if the XPath matches the node and returns the NodeList of the matching * * @param node starting node * @return list of nodes matching the current XPath */ public NodeList matches(Node node){ if(Options.debug) Debug.dumpElem("MatchXPath.matches:"+expr+" elem",node); try { NodeList nl = (NodeList)xpexpr.evaluate(node,XPathConstants.NODESET); if(Options.debug){ int n=nl.getLength(); System.out.println(n+" matches"); for(int i=0;ifoobar Element a = doc.createElement("a"); doc.appendChild(a); Element b = doc.createElement("b"); a.appendChild(b); b.setAttribute("id", "1"); Element c = doc.createElement("c"); b.appendChild(c); c.appendChild(doc.createTextNode("foo")); Element d = doc.createElement("d"); a.appendChild(d); Node startNode=doc.getDocumentElement().getFirstChild(); Debug.dumpElem(null, startNode); // quelques tests pour tenter de comprendre le comportement de l'évaluation XPath String[] tests = {"/a/b",".","./a","a","self::b","c","//c","b[@id=1]","b[@id=1]/c","*","/a/b/@id"}; NamespaceContext context = new NamespaceContext(); for(String t:tests){ XPath mxp=new XPath(t,context); NodeList elems=mxp.matches(startNode); if(elems.getLength()==0) System.out.println(mxp+":null"); else for(int i=0;i