I’m trying to learn some XML Parsing here and I’ve been given some code to start out with. I’ve done some research into the different API’s i’m using and I’ve gradually been able to debug my code into something I hope will work. I’m trying to parse XML files by hard wiring the XPath Query’s into a string variable. I’m also using DocumentBuilderFactory if that helps at all. Anyway, I keep getting this exception: Java.lang.String cannot be cast to org.w3c.dom.Node (I’ve marked it in the code below). I understand what the errors is. The String Query doesn’t seem to agree with the parameters of the “evaluate” method. Just don’t know how to fix it. I’ve tried all sorts of different casts and they aern’t working. Something tells me I’m doing something horribly wrong here…please help!
PS. I’m sorry my code is a but messy, i’m totally new to parsing, I also know there are some unnecessary imports but I figure I may need them if I make a few changes.
Code:
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import org.jaxen.JaxenException;
import org.jaxen.dom.DOMXPath;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class Parser
{
public static void main(String[] args)
{
boolean isNamespaceAware = true;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(isNamespaceAware);
DocumentBuilder builder = null;
try
{
builder = dbf.newDocumentBuilder();
}
catch (ParserConfigurationException e2)
{
e2.printStackTrace();
}
try
{
Document workingDocument =
builder.parse("C:\\Users\\Brandon\\Job\\XPath\\XPath_Sample_Stuff\\XPath_Objects.xml");
}
catch (SAXException e1)
{
e1.printStackTrace();
}
catch (IOException e1)
{
e1.printStackTrace();
}
String xPathQuery = "/book/author";
DOMXPath generatedPath;
String results = null;
try
{
generatedPath = new DOMXPath(xPathQuery);
//Here is the errror
results = generatedPath.evaluate(xPathQuery);
}
catch (JaxenException e)
{
e.printStackTrace();
}
if(results == null)
System.err.println("There was an issue processing the xpath, and
results were still null.");
for (int i=0; i<= results.getLength();i++)
{
System.out.println(results.item(i));
}
}
}
Here is some XML from an XML file I was given:
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with XML.</description>
</book>
The error is telling you that the
DOMXPath#evaluate(...)method returns a String. You are trying to cast it as a NodeList, which it is not. The API for this method will explain all — but again, that API is not part of standard Java but instead is part of Jaxen. But the result makes sense even for core Java since itsXPath#evaluate(...)method also usually returns a String (except for one overload).Again, perhaps you don’t want to use Jaxen just now, unless you have some strong reasons for doing so but haven’t told us yet.
Edit
Say you had an XML in a file, Catalog.xml, that looked like so:
JAXB could marshall/unmarshall that sucker with just some annotations in your regular classes. It makes doing this almost idiot proof. For example: