title: namespace-unaware XPath expression fails if Saxon is on the CLASSPATH
body: <p>I have the following sample XML file:</p>
  
  <pre><code>&lt;a xmlns="http://www.foo.com"&gt;
      &lt;b&gt;
      &lt;/b&gt;
  &lt;/a&gt;
  </code></pre>
  
  <p>Using the <code>XPath</code> expression <code>/foo:a/foo:b</code> (with <code>'foo'</code> properly configured in the <code>NamespaceContext</code>) I can correctly count the number of <code>b</code> nodes and the code works both when <code>Saxon-HE-9.4.jar</code> is on the CLASSPATH and when it's not.</p>
  
  <p>When, however, I parse the same file with a namespace-<strong>unaware</strong> <code>DocumentBuilderFactory</code>, the XPath expression "/a/b" correctly counts the number of <code>b</code> nodes only when <code>Saxon-HE-9.4.jar</code> is <strong>not</strong> on the CLASSPATH.</p>
  
  <p>Code below:</p>
  
  <pre><code>import java.io.*;
  import java.util.*;
  import javax.xml.xpath.*;
  import javax.xml.parsers.*;
  import org.w3c.dom.*;
  import javax.xml.namespace.NamespaceContext;
  
  public class FooMain {
  
      public static void main(String args[]) throws Exception {
  
          String xmlSample = "&lt;a xmlns=\"http://www.foo.com\"&gt;&lt;b&gt;&lt;/b&gt;&lt;/a&gt;";
          {
              XPath xpath = namespaceUnawareXpath();
              System.out.printf("[NS-unaware] Number of 'b' nodes is: %d\n", 
                                ((NodeList) xpath.compile("/a/b").evaluate(stringToXML(xmlSample, false),
                                XPathConstants.NODESET)).getLength());
          }
          {
              XPath xpath = namespaceAwareXpath("foo", "http://www.foo.com");
              System.out.printf("[NS-aware  ] Number of 'b' nodes is: %d\n", 
                                ((NodeList) xpath.compile("/foo:a/foo:b").evaluate(stringToXML(xmlSample, true),
                                 XPathConstants.NODESET)).getLength());
          }
  
      }
  
  
      public static XPath namespaceUnawareXpath() {
          XPathFactory xPathfactory = XPathFactory.newInstance();
          XPath xpath = xPathfactory.newXPath();
          return xpath;
      }
  
      public static XPath namespaceAwareXpath(final String prefix, final String nsURI) {
          XPathFactory xPathfactory = XPathFactory.newInstance();
          XPath xpath = xPathfactory.newXPath();
          NamespaceContext ctx = new NamespaceContext() {
                  @Override
                  public String getNamespaceURI(String aPrefix) {
                      if (aPrefix.equals(prefix))
                          return nsURI;
                      else
                          return null;
                  }
                  @Override
                  public Iterator getPrefixes(String val) {
                      throw new UnsupportedOperationException();
                  }
                  @Override
                  public String getPrefix(String uri) {
                      throw new UnsupportedOperationException();
                  }
              };
          xpath.setNamespaceContext(ctx);
          return xpath;
      }    
  
      private static Document stringToXML(String s, boolean nsAware) throws Exception {
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          factory.setNamespaceAware(nsAware);
          DocumentBuilder builder = factory.newDocumentBuilder();
          return builder.parse(new ByteArrayInputStream(s.getBytes("UTF-8")));
      }
  
  
  }
  </code></pre>
  
  <p>Running the above with:</p>
  
  <pre><code>java -classpath dist/foo.jar FooMain
  </code></pre>
  
  <p>.. produces:</p>
  
  <pre><code>[NS-unaware] Number of 'b' nodes is: 1
  [NS-aware  ] Number of 'b' nodes is: 1
  </code></pre>
  
  <p>Running with:</p>
  
  <pre><code>java -classpath Saxon-HE-9.4.jar:dist/foo.jar FooMain
  </code></pre>
  
  <p>... produces:</p>
  
  <pre><code>[NS-unaware] Number of 'b' nodes is: 0
  [NS-aware  ] Number of 'b' nodes is: 1
  </code></pre>