Unable to evaluate expression in XPath

17,580

The exception "Unable to evaluate expression using this context" may also result from a null document when trying to evaluate an XPath expression. (I had the same error and it took me a while to figure out I did not initialize my document properly).

In your code you have

try {
  // load document
}
catch (Exception ex) {
  System.err.println("unable to load XML: " + ex);
}

// happily continue

This is a call for trouble. If an exception happens during initialization you should STOP right there and you should not continue. If you have absolutely no idea how to handle the error, use catch(Exception e) { throw new Error(e); }. This will cause exceptions to bubble up and hopefully be handled by the default exception handler which prints a stack trace and exits.

As the reader of your question I don't even know where the exception was thrown. You should provide this information. Note that you can also use someException.printStackTrace(); to get the stack trace which points you to the correct line.

Share:
17,580
Muhammed Refaat
Author by

Muhammed Refaat

I'm a Software Engineer, mainly a mobile app developer, you can consider me Flutter developer, Android developer, Java developer, and can have a little conversation with python, assembly, php, (HTML-JS-CSS), and C#. And to make a little self satisfaction I can play a little with Photoshop and design some stuff. It's always my pleasure to know developers from all over the world, so if you wanna to get in touch with me: https://eg.linkedin.com/in/muhammed-refaat-582b386a [email protected] mo7amed.ref3at

Updated on June 15, 2022

Comments

  • Muhammed Refaat
    Muhammed Refaat about 2 years

    I;m using XPath to parse XML document returned by a URL, when i run my code with given inputs it works but when giving it inputs as a user input it throws an exception. The Code:

        class{
            private String generalQuery =  "//@*";
        method(){
            System.out.println("Enter URL");
            url = scan.nextLine();
            URL oracle = new URL(url);
            InputStream is = oracle.openStream();
    
            org.w3c.dom.Document doc = null;
            DocumentBuilderFactory domFactory;
            DocumentBuilder builder;
    
            try {
                domFactory = DocumentBuilderFactory.newInstance();
                domFactory.setNamespaceAware(true);
                builder = domFactory.newDocumentBuilder();
                doc = builder.parse(is);
            } catch (Exception ex) {
                System.err.println("unable to load XML: " + ex);
            }
    
        Map <String, String> params = new HashMap<String, String> ();
    
                XPathFactory factory = XPathFactory.newInstance();
                XPath xpath = factory.newXPath();
                xpath.setNamespaceContext(new NameSpaces(doc));
                XPathExpression expr = xpath.compile(generalQuery);
                Object result = expr.evaluate(doc, XPathConstants.NODESET); // exception thrown here
    
                NodeList nl = (NodeList) result;
    
                for (int i = 0 ; i < nl.getLength() ; i++){
                    Node n = (Node)nl.item(i);
                    params.put(n.getNodeName(), n.getNodeValue());
                }
    
                return params;
    }
    }
    

    The Exception:

    javax.xml.transform.TransformerException: Unable to evaluate expression using this context
    

    The class NameSpaces :

    import java.util.Iterator;
    import javax.xml.XMLConstants;
    import javax.xml.namespace.NamespaceContext;
    import org.w3c.dom.Document;
    
    public class NameSpaces implements NamespaceContext {
        private Document sourceDocument;
    
        public NameSpaces(Document document) {
            sourceDocument = document;
        }
    
        @Override
        public String getNamespaceURI(String prefix) {
            if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
                return sourceDocument.lookupNamespaceURI(null);
            } else {
                return sourceDocument.lookupNamespaceURI(prefix);
            }
        }
    
        @Override
        public String getPrefix(String namespaceURI) {
            return sourceDocument.lookupPrefix(namespaceURI);
        }
    
        @Override
        public Iterator<String> getPrefixes(String namespaceURI) {
            return null;
        }
    }
    
  • Wayne
    Wayne about 11 years
    This is probably right, but the OP didn't really include enough information to know for sure.
  • Muhammed Refaat
    Muhammed Refaat about 11 years
    i had already made that, the something is the name of the class NameSpaceResolver is just NameSpaces in my code
  • User0
    User0 about 11 years
    @Brass Block: Maybe you also could show us the XML. Does the xml have proper namespace declarations?
  • Lawrence Tierney
    Lawrence Tierney almost 7 years
    Yep in my case the error was due to a null document. This was the result of an upstream bug. Thanks.