Error while executing xpath expression on a NodeList
Hi
the following is the code snippet where I am obtaining a NodeList and then passing the nodelist to another xpath evaluate function.
I am not able to execute the xpath expression on the node list. Can you please tell me what could be the error...
The code and XML file are as below...
String xpathExpr ="/library/country/books";
NodeList nlist = (NodeList)xpathEvaluator.evaluate(xpathExpr, w3cdom, XPathConstants.NODESET);
xpathExpr ="/books/book/title";
String value = (String)xpathEvaluator.evaluate(xpathExpr, nlist, XPathConstants.STRING)
System.out.println("VALUE ==== " + value);
<?xml version="1.0" encoding="UTF-8"?>
<library>
<country>
<books>
<book type="hardback" lang="EN">
<title>Atlas & Shrugged</title>
<author>Ayn Rand</author>
<isbn>0525934189</isbn>
<price>39.95</price>
</book>
<book type="paperback" lang="JP">
<title>A Burnt-Out Case</title>
<author>Graham Greene</author>
<isbn>0140185399</isbn>
<price>13.00</price>
</book>
</books>
</country>
<country>
<books>
<book type="hardback" lang="EN">
<title>Atlas & Shrugged</title>
<author>Ayn Rand</author>
<isbn>0525934189</isbn>
<price>39.95</price>
</book>
<book type="paperback" lang="JP">
<title>A Burnt-Out Case</title>
<author>Graham Greene</author>
<isbn>0140185399</isbn>
<price>13.00</price>
</book>
</books>
</country>
</library>
Thanks.
[2236 byte] By [
KartikVa] at [2007-10-2 8:34:34]

It might help if you copy/pasted the exact complete error message.
I'm not going to go digging into those APIs at the moment, but it looks to me like you're trying to evaluate your second xpath expression relative to the first. If this is in fact the case, you should probably remove the leading "books" from the second one, or the trailing "books" from the first one. No? That is, it looks to me like you're searching for /library/country/books/books/book/title.
jverda at 2007-7-16 22:36:00 >

Hmm, if you specify an absolute path
"/books/book/title"
from a nodeset, does that mean it's starts from the nodeset, or the root of the document from which the nodeset was taken?
I would have thought from the document
This would imply to me that the nodes
library and books are at the same level
but perhaps i am wrong.
No. XPath has a "context node" from which its searches take place. If you start with a slash, you start at the current context node. If you start with noslash, you are looking for a child of the context node.
If you start with two slashes, you start at the root element of the document.
Try taking off the starting slash on the second string, then the "books", then the next slash until you get something that works.
Welcome to XPath.
Dave Patterson
hmm two slashes means descendants of the root, no? and one slash means from the root?
http://www.w3schools.com/xpath/xpath_syntax.asp
nodename Selects all child nodes of the node
/ Selects from the root node
// Selects nodes in the document from the current node that match the selection no matter where they are
bookstoreSelects all the child nodes of the bookstore element
/bookstoreSelects the root element bookstore
Note: If the path starts with a slash ( / ) it always represents an absolute path to an element!
bookstore/bookSelects all book elements that are children of bookstore
//bookSelects all book elements no matter where they are in the document
bookstore//bookSelects all book elements that are descendant of the bookstore element, no matter where they are under the bookstore element
jverda at 2007-7-16 22:36:00 >

right -- thats what i thought. so having an absolute path as the second xpath is wrong.
Hi ,
First and foremost thanks for all your replies. It was indeed helpful.
I should blame it on my oversight for the books in the second xpath expression. My second xpath expression would now read as
xpathExpr = "/book/title";
But unlucky as I am, it still does not work. ;)
In order to understand xpath better I tried this following example , this does not work as well. The code below reads an xml from a string and does a bit of rendering on the read nodelist. The error i get is below the code.
Kindly let me know where i am going wrong...
Thanks.
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
public class RenderTextXML {
public static void main(String args[]) throws XPathExpressionException, SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
String xpathExpr = "/subdoc";
//I tried even this xpath to get all the child nodes
//String xpathExpr = "subdoc";
//
String xml = "<subdoc count=\"8\" lang=\"EN\"><paragraph group=\"0\" type=\"STM\">I 1. A method of packaging a plurality of articles, the method comprising the steps of:</paragraph></subdoc>";
System.out.println(xml);
InputStream is = new java.io.ByteArrayInputStream(xml.getBytes("UTF-8"));
streamToString(is,"SUBDOC");
//
XPath xpathEvaluator = XPathFactory.newInstance().newXPath();
NodeList nlist = (NodeList) xpathEvaluator.evaluate(xpathExpr, is, XPathConstants.NODE);
System.out.println("Node List :" + nlist);
System.out.println("=======================================================");
int indentPos = 0;
for(int i = 0; i < nlist.getLength(); i++) {
System.out.println("Entered the for loop");
indentPos = 1;
if(nlist.item(i).hasAttributes()) {
NamedNodeMap attrMap = nlist.item(i).getAttributes();
String attrValue = attrMap.getNamedItem("type").getNodeValue();
if(attrValue.equalsIgnoreCase("STM")) {
System.out.print(nlist.item(i)+"");
} else if(attrValue.equalsIgnoreCase("PAR")) {
System.out.print(""
+ nlist.item(i) + "
");
} else if(attrValue.equalsIgnoreCase("PAC")) {
System.out.print("<center>"+nlist.item(i)+"</center>");
} else {
attrValue = attrValue.substring(2,attrValue.length());
int indentValue = new Integer(attrValue).intValue();
indentPos = indentPos * indentValue;
//System.out.print("<list>");
for(int j = 0;j < indentPos;j++) {
System.out.print("<ul>");
}
System.out.print("<li>"+nlist.item(i)+"</li>");
for(int j = 0;j < indentPos;j++) {
System.out.print("</ul>");
}
// System.out.print("</list>");
}
}
}
}
private static void streamToString(InputStream is, String fieldName) {
StringBuffer sb = new StringBuffer();
BufferedReader bfr = new BufferedReader(new InputStreamReader(is));
try {
String line = null;
while((line = bfr.readLine()) != null) {
sb.append(line);
}
} catch(Exception ex) {
ex.getMessage();
} finally {
try {
is.close();
} catch(Exception ex) {
}
}
System.out.println(fieldName + " : " + sb.toString() + "\n");
}
}
Sorry , I forgot to include my exception stack trace
<subdoc count="8" lang="EN"><paragraph group="0" type="STM">I 1. A method of packaging a plurality of articles, the method comprising the steps of:</paragraph></subdoc>
Exception in thread "main"
javax.xml.transform.TransformerException: Unknown error in XPath.
at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at RenderTextXML.main(RenderTextXML.java:32)
Caused by: java.lang.NullPointerException
at com.sun.org.apache.xpath.internal.axes.ChildTestIterator.setRoot(Unknown Source)
at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(Unknown Source)
at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(Unknown Source)
... 4 more
java.lang.NullPointerException
at com.sun.org.apache.xpath.internal.axes.ChildTestIterator.setRoot(Unknown Source)
at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(Unknown Source)
at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(Unknown Source)
at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at RenderTextXML.main(RenderTextXML.java:32)
linked to
javax.xml.xpath.XPathExpressionException
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at RenderTextXML.main(RenderTextXML.java:32)
Caused by: javax.xml.transform.TransformerException: Unknown error in XPath.
at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source)
... 2 more
Caused by: java.lang.NullPointerException
at com.sun.org.apache.xpath.internal.axes.ChildTestIterator.setRoot(Unknown Source)
at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(Unknown Source)
at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(Unknown Source)
... 4 more
i still vote forxpathExpr = "book/title";not xpathExpr = "/book/title";
Hi ,If thats the case , I tried the above program , where subdoc is my root note , i tried /subdoc andsubdoc but it still does not work. Where am i going wrong, please suggest.Thanks.
There are no <subdoc> elements anywhere in the XML document you posted so neither of those possibilities should return anything.
Hi,Please see my post (reply) , one before the penultimate, I was refering to the subdoc tags in the post.Thanks.