3

I have XML file andi'm trying to use XPath to get all the values for it's paths, but it doesn't generate values for the NameSpaces like :

//rss/channel/item/yweather:forecast/@low

OR

//rss/channel/yweather:wind/text()

The CODE : The Methods Used:

public class XmlSource{
    private XPathFactory factory = XPathFactory.newInstance();
    private XPath xpath = factory.newXPath();

    public Map<String, Object> update(String XML) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException, TransformerException{

            XmlSource xml = new XmlSource();
            Map<String, Object> result = new HashMap<String, Object>();

            Document doc = convert(XML); // converting the String to a document (tested and working efficiently)
            xml.doc = doc; 
            xpath.setNamespaceContext(new NamespaceResolver(xml.doc));

            ArrayList<String> paths = xml.getAllPaths(); // to get the listed above paths (tested and working efficiently)  

                for(int i=0; i < paths.size() ; i++){
                result.put(paths.get(i), getValue(paths.get(i), xml.doc));
                }
            return result;

        }
    public String getValue(String path, Document doc) throws TransformerException, IOException, ParserConfigurationException, SAXException {


                this.doc = doc;


            try {

                XPathExpression expr = xpath.compile(path);
                Object result = expr.evaluate(this.doc, XPathConstants.STRING);

                return result.toString();
            } catch (XPathExpressionException ex) {
                return null;
            }
        }

}

The NamespaceResolver class:

import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import org.w3c.dom.Document;

public class NamespaceResolver implements NamespaceContext {
    private Document sourceDocument;

    public NamespaceResolver(Document document) {
        sourceDocument = document;
    }

    @Override
    public String getNamespaceURI(String prefix) {
        if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
            return sourceDocument.lookupNamespaceURI(null);
        } else {
            return sourceDocument.lookupNamespaceURI(prefix);
        }
    }

    @Override
    public String getPrefix(String namespaceURI) {
        return sourceDocument.lookupPrefix(namespaceURI);
    }

    @Override
    public Iterator<String> getPrefixes(String namespaceURI) {
        return null;
    }
}

The Exceptions Thrown:

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    --------------- linked to ------------------
    javax.xml.xpath.XPathExpressionException
        org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    //rss/channel/item/yweather:condition/@text
    //rss/channel/item/yweather:forecast/@code
    //rss/channel/item/yweather:forecast/@date
    //rss/channel/item/yweather:forecast/@day
    //rss/channel/item/yweather:forecast/@high
    //rss/channel/item/yweather:forecast/@low
    //rss/channel/item/yweather:forecast/@text
    //rss/channel/item/yweather:forecast/@code
    //rss/channel/item/yweather:forecast/@date
    //rss/channel/item/yweather:forecast/@day
    //rss/channel/item/yweather:forecast/@high
    //rss/channel/item/yweather:forecast/@low
    //rss/channel/item/yweather:forecast/@text
    --------------- linked to ------------------
    javax.xml.xpath.XPathExpressionException
    dAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: com.sun.org.apache.xpath.internal.domapi.XPathStylesheetDOM3Exception: Prefix must resolve to a namespace: yweather
        at com.sun.org.apache.xpath.internal.compiler.XPathParser.errorForDOM3(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.Lexer.mapNSTokens(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.Lexer.tokenize(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.Lexer.tokenize(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(Unknown Source)
        at com.sun.org.apache.xpath.internal.XPath.<init>(Unknown Source)
        at com.sun.org.apache.xpath.internal.XPath.<init>(Unknown Source)
        ... 30 more
    com.sun.org.apache.xpath.internal.domapi.XPathStylesheetDOM3Exception: Prefix must resolve to a namespace: yweather
        at com.sun.org.apache.xpath.internal.compiler.XPathParser.errorForDOM3(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.Lexer.mapNSTokens(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.Lexer.tokenize(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.Lexer.tokenize(Unknown Source)
        at com.sun.org.apache.xpath.internal.compiler.XPathParser.initXPath(Unknown Source)
        at com.sun.org.apache.xpath.internal.XPath.<init>(Unknown Source)
        at com.sun.org.apache.xpath.internal.XPath.<init>(Unknown Source)
        at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.compile(Unknown Source)
        at com.nc.inotify.dp.xml.impl.XmlSource.getValue(XmlSource.java:180)
        at com.nc.inotify.dp.xml.impl.XmlSource.update(XmlSource.java:284)
        at com.nc.inotify.dp.xml.impl.XmlSourceFactory.getSource(XmlSourceFactory.java:155)
        at com.nc.inotify.dp.xml.junit.TXmlSourceFactory.tesGetSource(TXmlSourceFactory.java:139)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    --------------- linked to ------------------
    javax.xml.xpath.XPathExpressionException
        at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.compile(Unknown Source)
        at com.nc.inotify.dp.xml.impl.XmlSource.getValue(XmlSource.java:180)
        at com.nc.inotify.dp.xml.impl.XmlSource.update(XmlSource.java:284)
        at com.nc.inotify.dp.xml.impl.XmlSourceFactory.getSource(XmlSourceFactory.java:155)
        at com.nc.inotify.dp.xml.junit.TXmlSourceFactory.tesGetSource(TXmlSourceFactory.java:139)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at 
    //rss/channel/item/yweather:forecast/text()
    //rss/channel/item/guid/text()
    DONE
4
  • 1
    I see you catch possible exceptions and return null in the update function. What happens if you just throw the exception (I think you might be getting one) and post the result? Commented Jun 3, 2013 at 21:11
  • i have already made this but it throws me like million exceptions so, i made it return null due to that, i will throw it again and edit the question with the result Commented Jun 4, 2013 at 7:57
  • i edited the question with a portion of the exception thrown, please have a look Commented Jun 4, 2013 at 11:38
  • I posted a suggestion as answer, but it hinges upon one assumption about the convert method you use. I hope it helps you! Commented Jun 4, 2013 at 15:36

1 Answer 1

10

I was able to reproduce your error by using a DocumentBuilderFactory that was not namespace aware.

Suppose your convert method looks something like this:

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputSource);

Then you could try this:

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(inputSource);

This would explain why the NamespaceResolver isn't able to get the namespaceURI.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.