Search code examples
javaxmlexceptionxpathtransformer-model

XPath compiling behaviour


I am testing my application and realised that behaviour is different when compiling.

For example, if my expression to compile is :

XPathExpression expr = xPath.compile("/DocDetails/TransactionSignature");

And :

XPathExpression expr2 = xPath.compile("/DocDetails/" + x); 

x is declared as a String datatype.

Lets say that x in expr2 is "abc", XPathExpression is compiled with no issues.

But if x in expr2 is "123abc" OR "123", XPathExpression throws a :

javax.xml.transform.TransformerException: A location step was expected following the '/' or '//' token.

Just curious regarding this behaviour..

Here is the full code for reference:

        String document = "C:/Users/Eunice/Documents/MITS/doc.xml";
        String document2 = "C:/Users/Eunice/Documents/MITS/doc2.xml";

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(document);

        Document doc2 = builder.parse(document2);

        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xPath = xPathFactory.newXPath();
        XPathExpression expr = xPath.compile("/DocDetails/TransactionSignature");
        Node node = (Node)expr.evaluate(doc, XPathConstants.NODE);

        String x = node.getTextContent();

        System.out.println(x);

        XPathExpression expr2 = xPath.compile("/DocDetails/" + x);
        Node node2 = (Node)expr2.evaluate(doc2, XPathConstants.NODE);

        if (node2 == null)
            System.out.println("null");
        else 
            System.out.println("not null " + node2.getTextContent());

And this is the XML file:

<DocDetails>
    <TransactionSignature>abc123</TransactionSignature>
</DocDetails>

Solution

  • I finally found the answer after much searching!

    It is actually illegal to start an element tag with numbers.

    As can be seen in this stackoverflow answer

    Originally, this line was throwing an transformer exception:

            XPathExpression expr2 = xPath.compile("/DocDetails/" + x); 
    

    Since it is illegal to start with numbers, they are probably reading it as an invalid tag.

    Which means this line is actually reading "/DocDetails/" instead of "/DocDetails/123" OR "/DocDetails/123abc",

    causing the extra '/' at the end, hence throwing an transformer exception.