1

I try to use XPath with namespaces, but I do not get it going the way I would expect it.

import org.springframework.util.xml.*;
import javax.xml.namespace.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;



public String foo () throws Exception
{   
    String xml = "<aaa:test xmlns:aaa=\"http://aaa\">123</aaa:test>";
    
    
    
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
    DocumentBuilder db = dbf.newDocumentBuilder ();
    Document doc = db.parse (new ByteArrayInputStream (xml.getBytes()));    //new ByteArrayInputStream (bodies.get (0)));
    
    
    
    XPath xp = XPathFactory.newInstance ().newXPath ();
    SimpleNamespaceContext snc = new SimpleNamespaceContext ();
    snc.bindNamespaceUri ("aaa", "http://aaa");
    xp.setNamespaceContext (snc);
    String str1 = (String) xp.compile ("/test").evaluate (doc, XPathConstants.STRING);
    String str2 = (String) xp.compile ("/aaa:test").evaluate (doc, XPathConstants.STRING);
    System.out.println ("str1="+str1 + "    str2="+str2);
    // output: str1=123    str2=

    
    
    
    xp = XPathFactory.newInstance ().newXPath ();
    xp.setNamespaceContext(new NamespaceContext() 
    {
        public String getNamespaceURI(String arg0)
        {
            if ("aaa".equals(arg0)) 
            {
                  return "http://aaa";
            }
            return null;
        }
        public String getPrefix(String arg0) {  
            return null;
        }
        public Iterator<String> getPrefixes(String arg0) {
            return null;
        }
    });
    str1 = (String) xp.compile ("/test").evaluate (doc, XPathConstants.STRING);
    str2 = (String) xp.compile ("/aaa:test").evaluate (doc, XPathConstants.STRING);
    System.out.println ("str1="+str1 + "    str2="+str2);
    // output: str1=123    str2=
}

I would - at least - expect str2 to be equal to str1. Or better str2 with the value 123 and str1 with nothing - if namespaces are in use.

But what I get is str1 with the value and str2 with nothing.

I expect to use the namespace in the XPath query if one is in use. but it does not get me the value.

As you can see, I tried to define the namespace in two different ways, but none seems to be OK.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
chris01
  • 10,921
  • 9
  • 54
  • 93
  • Does this help? https://stackoverflow.com/questions/5239685/xml-namespace-breaking-my-xpath – hfontanez Jan 14 '22 at 20:19
  • Sorry, but no. It is working the way I expect it in other languages. But I do not get it in Java. – chris01 Jan 14 '22 at 20:24
  • If you examine the link I sent you in detail, you should notice that this line in your code, `snc.bindNamespaceUri ("aaa", "http://aaa");`, appears to be incorrect. The URL on that call should be the URL where that namespace is defined. – hfontanez Jan 14 '22 at 20:26
  • If you were binding the namespace in the actual XML, you would need to provide the URL where `table` is defined (for `aaa` namespace). That same URL is needed on the Java side. – hfontanez Jan 14 '22 at 20:29
  • 4
    Remember to call [setNamespaceAware(true)](https://docs.oracle.com/en/java/javase/17/docs/api/java.xml/javax/xml/parsers/DocumentBuilderFactory.html#setNamespaceAware(boolean)) on your DocumentBuilderFactory. It’s false by default. – VGR Jan 14 '22 at 20:55
  • Thank! That does the trick! – chris01 Jan 14 '22 at 22:10

0 Answers0