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

XPath Namespace resolver fails when namespace starts with a #

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3 P3
    • None
    • 6u7
    • xml
    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      java version "1.6.0_07"
      Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
      Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Windows XP

      A DESCRIPTION OF THE PROBLEM :
      When running a XPath query like:

      //z:row

      against
      <?xml version="1.0" encoding="utf-8"?>
      <test xmlns:rs="urn:schemas-microsoft-com:rowset"
           xmlns:z="#RowsetSchema">
      <rs:data>
        <z:row>XX</z:row>
      </rs:data>
      </test>

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

      The problem is the # sign in the xmlns:z="#RowsetSchema". If I rename the namespace to be just xmlns:z="RowsetSchema" then it works fine.

      This is an issue as Microsoft sharepoint webservices namespaces start with a #.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The following code shows a working and failing example:

      import com.sun.org.apache.xerces.internal.parsers.DOMParser;
      import java.io.StringReader;
      import java.util.Iterator;
      import javax.xml.XMLConstants;
      import javax.xml.namespace.NamespaceContext;
      import javax.xml.transform.TransformerException;
      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.NodeList;
      import org.xml.sax.InputSource;
       
      public class TestXPath {
       
          public static void main(String[] args) {
              try {
                  System.out.println("Running Test 1");
                  String test1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                          "<test xmlns:rs=\"urn:schemas-microsoft-com:rowset\" xmlns:z=\"#RowsetSchema\">" +
                              "<rs:data>" +
                                  "<z:row>XX</z:row>" +
                              "</rs:data>" +
                          "</test>";
                  DOMParser parser = new DOMParser();
                  parser.parse(new InputSource(new StringReader(test1)));
                  runXpathQueryTest( parser.getDocument(), "//z:row");
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }
       
              try {
                  System.out.println("Running Test 2 - Only difference is we have changed '#RowsetSchema' to 'RowsetSchema'");
                  String test1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                          "<test xmlns:rs=\"urn:schemas-microsoft-com:rowset\" xmlns:z=\"RowsetSchema\">" +
                              "<rs:data>" +
                                  "<z:row>XX</z:row>" +
                              "</rs:data>" +
                          "</test>";
                  DOMParser parser = new DOMParser();
                  parser.parse(new InputSource(new StringReader(test1)));
                  runXpathQueryTest( parser.getDocument(), "//z:row");
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }
       
          }
       
          private static void runXpathQueryTest(Document document, String xPathExpression)
                  throws XPathExpressionException, TransformerException {
       
       
              XPath xPath = XPathFactory.newInstance().newXPath();
              xPath.setNamespaceContext(new UniversalNamespaceResolver(document));
       
              NodeList result1 = (NodeList) xPath.evaluate( xPathExpression, document, XPathConstants.NODESET);
              System.out.println(xPathExpression + " returned " + result1.getLength() + " matching node(s)");
          }
       
          static class UniversalNamespaceResolver implements NamespaceContext {
              private Document sourceDocument;
       
              public UniversalNamespaceResolver(Document document) {
                  sourceDocument = document;
              }
       
              public String getNamespaceURI(String prefix) {
                  if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
                      return sourceDocument.lookupNamespaceURI(null);
                  } else {
                      return sourceDocument.lookupNamespaceURI(prefix);
                  }
              }
       
              public String getPrefix(String namespaceURI) {
                  return sourceDocument.lookupPrefix(namespaceURI);
              }
       
              public Iterator getPrefixes(String namespaceURI) {
                  // not implemented yet
                  return null;
              }
          }
      }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Running Test 1
      //z:row returned 1 matching node(s)

      Running Test 2 - Only difference is we have changed '#RowsetSchema' to 'RowsetSchema'
      //z:row returned 1 matching node(s)
      ACTUAL -
      Running Test 1
      javax.xml.transform.TransformerException: A location step was expected following the '/' or '//' token.
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.error(XPathParser.java:608)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.Step(XPathParser.java:1737)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelativeLocationPath(XPathParser.java:1624)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.LocationPath(XPathParser.java:1595)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.PathExpr(XPathParser.java:1315)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnionExpr(XPathParser.java:1234)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnaryExpr(XPathParser.java:1140)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.MultiplicativeExpr(XPathParser.java:1061)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.AdditiveExpr(XPathParser.java:1003)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelationalExpr(XPathParser.java:928)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.EqualityExpr(XPathParser.java:868)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.AndExpr(XPathParser.java:832)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.OrExpr(XPathParser.java:805)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.Expr(XPathParser.java:788)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(XPathParser.java:127)
              at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:176)
              at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:264)
              at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(XPathImpl.java:193)
              at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:275)
              at com.categoric.pindar.TestXPath.runXpathQueryTest(TestXPath.java:59)
              at com.categoric.pindar.TestXPath.main(TestXPath.java:30)
      --------------- linked to ------------------
      javax.xml.xpath.XPathExpressionException
              at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:289)
              at com.categoric.pindar.TestXPath.runXpathQueryTest(TestXPath.java:59)
              at com.categoric.pindar.TestXPath.main(TestXPath.java:30)
       
      ...cut...
       
      Running Test 2 - Only difference is we have changed '#RowsetSchema' to 'RowsetSchema'
      //z:row returned 1 matching node(s)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      javax.xml.transform.TransformerException: A location step was expected following the '/' or '//' token.
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.error(XPathParser.java:608)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.Step(XPathParser.java:1737)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelativeLocationPath(XPathParser.java:1624)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.LocationPath(XPathParser.java:1595)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.PathExpr(XPathParser.java:1315)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnionExpr(XPathParser.java:1234)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.UnaryExpr(XPathParser.java:1140)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.MultiplicativeExpr(XPathParser.java:1061)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.AdditiveExpr(XPathParser.java:1003)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.RelationalExpr(XPathParser.java:928)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.EqualityExpr(XPathParser.java:868)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.AndExpr(XPathParser.java:832)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.OrExpr(XPathParser.java:805)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.Expr(XPathParser.java:788)
              at com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(XPathParser.java:127)
              at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:176)
              at com.sun.org.apache.xpath.internal.XPath.<init>(XPath.java:264)
              at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(XPathImpl.java:193)
              at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:275)
              at com.categoric.pindar.TestXPath.runXpathQueryTest(TestXPath.java:59)
              at com.categoric.pindar.TestXPath.main(TestXPath.java:30)
      --------------- linked to ------------------
      javax.xml.xpath.XPathExpressionException
              at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:289)
              at com.categoric.pindar.TestXPath.runXpathQueryTest(TestXPath.java:59)
              at com.categoric.pindar.TestXPath.main(TestXPath.java:30)
       

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import com.sun.org.apache.xerces.internal.parsers.DOMParser;
      import java.io.StringReader;
      import java.util.Iterator;
      import javax.xml.XMLConstants;
      import javax.xml.namespace.NamespaceContext;
      import javax.xml.transform.TransformerException;
      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.NodeList;
      import org.xml.sax.InputSource;
       
      public class TestXPath {
       
          public static void main(String[] args) {
              try {
                  System.out.println("Running Test 1");
                  String test1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                          "<test xmlns:rs=\"urn:schemas-microsoft-com:rowset\" xmlns:z=\"#RowsetSchema\">" +
                              "<rs:data>" +
                                  "<z:row>XX</z:row>" +
                              "</rs:data>" +
                          "</test>";
                  DOMParser parser = new DOMParser();
                  parser.parse(new InputSource(new StringReader(test1)));
                  runXpathQueryTest( parser.getDocument(), "//z:row");
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }
       
              try {
                  System.out.println("Running Test 2 - Only difference is we have changed '#RowsetSchema' to 'RowsetSchema'");
                  String test1 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                          "<test xmlns:rs=\"urn:schemas-microsoft-com:rowset\" xmlns:z=\"RowsetSchema\">" +
                              "<rs:data>" +
                                  "<z:row>XX</z:row>" +
                              "</rs:data>" +
                          "</test>";
                  DOMParser parser = new DOMParser();
                  parser.parse(new InputSource(new StringReader(test1)));
                  runXpathQueryTest( parser.getDocument(), "//z:row");
              } catch (Exception e) {
                  e.printStackTrace(System.out);
              }
       
          }
       
          private static void runXpathQueryTest(Document document, String xPathExpression)
                  throws XPathExpressionException, TransformerException {
       
       
              XPath xPath = XPathFactory.newInstance().newXPath();
              xPath.setNamespaceContext(new UniversalNamespaceResolver(document));
       
              NodeList result1 = (NodeList) xPath.evaluate( xPathExpression, document, XPathConstants.NODESET);
              System.out.println(xPathExpression + " returned " + result1.getLength() + " matching node(s)");
          }
       
          static class UniversalNamespaceResolver implements NamespaceContext {
              private Document sourceDocument;
       
              public UniversalNamespaceResolver(Document document) {
                  sourceDocument = document;
              }
       
              public String getNamespaceURI(String prefix) {
                  if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
                      return sourceDocument.lookupNamespaceURI(null);
                  } else {
                      return sourceDocument.lookupNamespaceURI(prefix);
                  }
              }
       
              public String getPrefix(String namespaceURI) {
                  return sourceDocument.lookupPrefix(namespaceURI);
              }
       
              public Iterator getPrefixes(String namespaceURI) {
                  // not implemented yet
                  return null;
              }
          }
      }
      ---------- END SOURCE ----------

            joehw Joe Wang
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Imported:
              Indexed: