views:

29

answers:

1

I have the following code and have had some trouble with a specific field and it's output. The namespace is connected but doesn't seem to be outputting on the required field. Any info on this would be great.

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

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import java.io.ByteArrayInputStream;
import java.io.IOException;

public class test
{
 public static void main(String args[])

 {


     String xmlStr =    "<aws:UrlInfoResponse xmlns:aws=\"http://alexa.amazonaws.com/doc/2005-10-05/\"&gt;\n" +
                "    <aws:Response xmlns:aws=\"http://awis.amazonaws.com/doc/2005-07-11\"&gt;\n" +
                "        <aws:OperationRequest>\n" +
                "            <aws:RequestId>blah</aws:RequestId>\n" +
                "        </aws:OperationRequest>\n" +
                "        <aws:UrlInfoResult>\n" +
                "            <aws:Alexa>\n" +
                "                <aws:TrafficData>\n" +
                "                    <aws:DataUrl type=\"canonical\">harvard.edu/</aws:DataUrl>\n" +
                "                    <aws:Rank>1635</aws:Rank>\n" +
                "                </aws:TrafficData>\n" +
                "            </aws:Alexa>\n" +
                "        </aws:UrlInfoResult>\n" +
                "        <aws:ResponseStatus xmlns:aws=\"http://alexa.amazonaws.com/doc/2005-10-05/\"&gt;\n" +
                "            <aws:StatusCode>Success</aws:StatusCode>\n" +
                "        </aws:ResponseStatus>\n" +
                "    </aws:Response>\n" +
                "</aws:UrlInfoResponse>";

                    DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();

                    xmlFact.setNamespaceAware(true);

        DocumentBuilder builder = null;
        try {
            builder = xmlFact.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();       }

        Document doc = null;
        try {
            doc = builder.parse(

     new ByteArrayInputStream( xmlStr.getBytes()));
        } catch (SAXException e) {
            e.printStackTrace();     } catch (IOException e) {
            e.printStackTrace();       }






     System.out.println(doc.getDocumentElement().getNamespaceURI());
     System.out.println(xmlFact.isNamespaceAware());

  String xpathStr = "//aws:OperationRequest";

            XPathFactory xpathFact = XPathFactory.newInstance();

            XPath xpath = xpathFact.newXPath();

        String result = null;
        try {
            result = xpath.evaluate(xpathStr, doc);
        } catch (XPathExpressionException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        System.out.println("XPath result is \"" +  result + "\"");


}
}
+1  A: 

namespace matching in an Xpath isn't just string matching the prefix. You have to actually define a NamespaceContext object and associate it with the xPath. It doesn't even actually matter at all if the prefixes are the same in the document and in the xPath

private NamespaceContext ns = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
if (prefix.equals("ns1") return "http://alexa.amazonaws.com/doc/2005-10-05/";
else return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String namespace) {
throw new UnsupportedOperationException();
}
public Iterator getPrefixes(String namespace) {
throw new UnsupportedOperationException();
}};

XPathFactory xpfactory = XPathFactory.newInstance();
XPath xpath = xpfactory.newXPath();
xpath.setNamespaceContext(ns);

String xpathStr = "//ns1:OperationRequest";
//and so on
Affe