Project

Profile

Help

XPATH query always throws null exception

Added by Anonymous over 18 years ago

Legacy ID: #3351041 Legacy Poster: Anurag Chakravarti (anurag2002)

Hi, I always get a null exception while using XPATH evaluator Saxon-8.5.1b. I am using this for the first time. My xml document is: <foo xmlns="default-namespace"> <ns1:bar xmlns:ns1="namespace1-uri" xmlns="namespace1-uri"> <baz/> <ns2:baz xmlns:ns2="namespace2-uri"/> </ns1:bar> <ns3:hi xmlns:hi="namespace3-uri"> <there/> </ns3:hi> </foo> XPATH expression is /foo/a:bar/b:baz java code is: String xpathExpr = "/foo/a:bar/b:baz"; try { XPathFactory xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON); } catch( javax.xml.xpath.XPathFactoryConfigurationException exception ) { System.out.println( "Exception XPathFactory.newInstance" ); } StandaloneContext context = new StandaloneContext(); context.declareNamespace("a","namespace1-uri"); context.declareNamespace("b","namespace1-uri"); NamespaceContext namespaceContext = new NamespaceContextImpl(context); InputSource is = new InputSource(xmlExpr); SAXSource ss = new SAXSource(is); XPathEvaluator xpe = new XPathEvaluator(); xpe.setNamespaceContext(namespaceContext); String result = null; try { result = xpe.evaluate(xpathExpr, ss); } catch( javax.xml.xpath.XPathExpressionException exception ) { System.out.println( exception.getCause() ); } I always get a exception and exception.getCause gives me null. Any suggestions would be of great help. As you can see I am new to all this :-) Thanks -Anurag


Replies (4)

Please register to reply

RE: XPATH query always throws null exception - Added by Anonymous over 18 years ago

Legacy ID: #3351383 Legacy Poster: Michael Kay (mhkay)

First of all, your code is not showing the exception details. exception.getCause() only gives a small part of the information. As a minimum you should display the value of exception.getMessage(), and in most cases, at least during development, it's useful to display a stack trace. You're creating an XPathFactory but you aren't using it to create the XPath instance. However, I don't think this is relevant to your problem. The interface javax.xml.xpath.XPath, which Saxon's XPathEvaluator implements, has two 2-argument methods called evaluate(). One of them takes an InputSource as the second argument, the other takes an Object which is supposed to represent a Node in the chosen object model. You have supplied a SAXSource, so the second method is called: Saxon complains that it doesn't recognize SAXSource as a node, and your code fails to display the error message. If you change it to supply the InputSource as the second argument (and to display the error messages), you get this: Error on line 6 column 36 SXXP0003: Error reported by XML parser: The prefix "ns3" for element "ns3:hi" is not bound. If you then correct the XML source (change xmlns:hi to xmlns:ns3) then the XPath expression is successfully evaluated, and returns an empty string. If you change the namespace binding for b to bind to namespace2, and add a prefix that binds the default namespace, and give the baz element some content, and display the content of result, then you can see that the query works. The code now looks like this: String xpathExpr = "/d:foo/a:bar/b:baz"; StandaloneContext context = new StandaloneContext(); context.declareNamespace("d", "default-namespace"); context.declareNamespace("a", "namespace1-uri"); context.declareNamespace("b", "namespace2-uri"); NamespaceContext namespaceContext = new NamespaceContextImpl(context); InputSource is = new InputSource(new FileInputStream(new File("c:/temp/test.xml"))); XPathEvaluator xpe = new XPathEvaluator(); xpe.setNamespaceContext(namespaceContext); String result = xpe.evaluate(xpathExpr, is); System.err.println(result); Michael Kay

RE: XPATH query always throws null exception - Added by Anonymous over 18 years ago

Legacy ID: #3352446 Legacy Poster: Anurag Chakravarti (anurag2002)

Thanks a lot. It worked out, But for the below xml document, the query "/foo/a:bar" <?xml version="1.0" encoding="UTF-8"?> <foo xmlns:d="default-namespace"> <ns1:bar xmlns:ns1="namespace1-uri" xmlns="namespace1-uri"> <ns1:baz> <hey>hello 1</hey> </ns1:baz> <ns2:baz xmlns:ns2="namespace2-uri"> <hey>hello 2</hey> </ns2:baz> </ns1:bar> </foo> gives output hello1 hello2 I want to print the elements also and along with the values. Is this possible? Regards -Anurag

RE: XPATH query always throws null exception - Added by Anonymous over 18 years ago

Legacy ID: #3352492 Legacy Poster: Michael Kay (mhkay)

There are various methods in the XPath API. The one that you are calling converts the result of the path expression to a string (by taking the string value of the selected nodes). There are other methods that return the nodes themselves, which would allow you to serialize the tree structure underneath those nodes (for example, by doing a JAXP identity transform to a StreamResult). However, for this kind of thing you're probably much better off using XQuery. XQuery allows you to construct a result tree, rather than just selecting nodes in the input document, and it gives you the option of serializing the result tree using all the serialization parameters available in xsl:output.

RE: XPATH query always throws null exception - Added by Anonymous over 18 years ago

Legacy ID: #3352692 Legacy Poster: Anurag Chakravarti (anurag2002)

Hi, With all your help I got the final xml document. Thanks a lot. I am using XPATH as it is recommended for XCAP protocol. I am giving the piece of code below which is working for other novices starting kick. You could comment on improvements: InputSource is = new InputSource(new FileInputStream("test.xml")); DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); dfactory.setNamespaceAware(true); Document doc = dfactory.newDocumentBuilder().parse(is); XPathFactory xpf = XPathFactory.newInstance(XPathConstants.DOM_OBJECT_MODEL); XPath xpe = xpf.newXPath(); StandaloneContext context = new StandaloneContext(); context.declareNamespace("a","namespace1-uri"); context.declareNamespace("b","namespace2-uri"); context.declareNamespace("d","default-namespace"); NamespaceContext namespaceContext = new NamespaceContextImpl(context); xpe.setNamespaceContext(namespaceContext); XPathExpression xpathExpression = xpe.compile("/d:foo/a:bar/*"); NodeList nodeList = (NodeList)xpathExpression.evaluate((Object)doc, XPathConstants.NODESET); System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); for(int i=0; i<nodeList.getLength(); i++) { Node node = (Node)nodeList.item(0); LSSerializer writer = impl.createLSSerializer(); String str = writer.writeToString(node); System.out.println("Final result to be sent: \n " + str);

    (1-4/4)

    Please register to reply