Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8268248

XPath Selection Expression "//" Does Not Return Correct Results for Context

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10, OpenJDK Runtime Environment (build 15.0.2+7-27)

      A DESCRIPTION OF THE PROBLEM :
      The XPath selection expression "double-slash" ("//") is supposed to select descendant nodes _from the current nodal context_ that match the selection regardless of where they are in the descending hierarchy. The current API gives an incorrect result which seems to be based not on the provided context node, but rather on the document as a whole. Regardless of what context it is ultimately operating on, it is incorrect.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Simply run "java XPathAPIProblem.java", then examine the results under the heading "FAULTY".

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      id="3"
      id="4"
      ACTUAL -
      id="1"
      id="2"
      id="3"
      id="4"
      id="5"
      id="6"

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.io.IOException;
      import java.io.InputStream;

      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.parsers.ParserConfigurationException;
      import javax.xml.xpath.XPath;
      import javax.xml.xpath.XPathConstants;
      import javax.xml.xpath.XPathExpressionException;
      import javax.xml.xpath.XPathFactory;

      import org.w3c.dom.Document;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      import org.xml.sax.SAXException;

      /*
       * Example for bug submission.
       *
       * @author
       */
      public class XPathAPIProblem
      {
      public static void main(String args[]) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException
      {
      DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
      dfactory.setNamespaceAware(true);
      DocumentBuilder docBuilder = dfactory.newDocumentBuilder();

      String xmlString = "<root>"
      + " <child>"
      + " <grandchild id='1'/>"
      + " <grandchild id='2'/>"
      + " </child>"
      + " <child>"
      + " <grandchild id='3'/>"
      + " <grandchild id='4'/>"
      + " </child>"
      + " <child>"
      + " <grandchild id='5'/>"
      + " <grandchild id='6'/>"
      + " </child>"
      + " </root>";
      InputStream is = new ByteArrayInputStream(xmlString.getBytes());
      Document doc = docBuilder.parse(is);

      XPath xPath = XPathFactory.newInstance().newXPath();
      NodeList children = (NodeList) xPath.evaluate("//child", doc, XPathConstants.NODESET);

      Node currentChild = children.item(1);
      NodeList faultyGrandchildren = (NodeList) xPath.evaluate("//grandchild", currentChild, XPathConstants.NODESET);
      NodeList workaroundGrandchildren = (NodeList) xPath.evaluate("child::grandchild", currentChild, XPathConstants.NODESET);

      // Faulty result
      System.out.println("FAULTY");

      for (int x = 0; x < faultyGrandchildren.getLength(); x++) {
      Node currentGrandchild = faultyGrandchildren.item(x);

      System.out.println(currentGrandchild.getAttributes().getNamedItem("id"));
      }

      // Correct result
      System.out.println("CORRECT");

      for (int x = 0; x < workaroundGrandchildren.getLength(); x++) {
      Node currentGrandchild = workaroundGrandchildren.item(x);

      System.out.println(currentGrandchild.getAttributes().getNamedItem("id"));
      }
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Since I was being lazy (but validly lazy), I was attempting to use "//" as a shortcut instead of "child::grandchild". I am aware that those two expressions are not equivalent, but given the context I am working with, they ought to return the same result. Using the latter worked for me.

      FREQUENCY : always


            joehw Joe Wang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: