XPathReader error: java.lang.String cannot be cast to org.w3c.dom.Node

I am trying to parse data from XML that has been obtained from a Clob type. For some reason, I am getting this exception... I can't figure out why. I have obtained the Clob from an oracle database column that contains an XMLType value, that is the XML. I have successfully extracted the XML contained from the XMLType to a Clob type. This is obtained with the following code:

xmlBean =  XmlHelper.xPathRead(film.getXmlClob());

the film object is in the model if you will, and the getXmlClob() method returns a Clob value that contains the XML I want to parse using XPath. Here is the rest of the code:

XMLHelper

public static XmlBean xPathRead(Clob xmlClob) {
    XPathReader reader = new XPathReader(xmlClob);
    XmlBean xmlBean = new XmlBean();   // just an entity from the model to store the xml's contents inside

    String filmId = "/IMAGE[1]/@id";
    xmlBean.setFilmId(Integer.parseInt((String) reader.read(filmId, XPathConstants.STRING)));
}

XPathReader

public class XPathReader {
    private String xmlString;
    private XPath xPath;

    public XPathReader(Clob xmlClob) {

        try {
            if ((int) xmlClob.length() > 0) {  
                String s = xmlClob.getSubString(1, (int) xmlClob.length()); // this is a way to cast a CLOB into a STRING
                this.xmlString = s;
              }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        xPath = XPathFactory.newInstance().newXPath();
    }

    public Object read(String expression, QName returnType) {
        try {
            XPathExpression xPathExpression = xPath.compile(expression);
            return xPathExpression.evaluate(xmlString, returnType);
        } catch (XPathExpressionException ex) {
            ex.printStackTrace();
            return null;
        }
    }
}

Any ideas? The problem resides in the evaluate() method...

Error message

java.lang.ClassCastException: java.lang.String cannot be cast to org.w3c.dom.Node at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.eval(Unknown Source) at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.eval(Unknown Source) at com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl.evaluate(Unknown Source) at helper.XPathReader.read(XPathReader.java:34) at helper.XmlHelper.xPathRead(XmlHelper.java:325)

Upvotes: 1

Views: 5220

Answers (1)

Woody
Woody

Reputation: 5130

you can't do it from a string anyway.

How about something like this

public class XPathReader {
  private XPath xPath;
  private Document doc;

  public XPathReader(Clob xmlClob) {

    try {
        if ((int) xmlClob.length() > 0) {  
            String s = xmlClob.getSubString(1, (int) xmlClob.length()); // this is a way to cast a CLOB into a STRING
            doc = readDoc(s);
          }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    xPath = XPathFactory.newInstance().newXPath();
}

public Object read(String expression, QName returnType) {
    try {
        XPathExpression xPathExpression = xPath.compile(expression);
        return xPathExpression.evaluate(doc, returnType);
    } catch (XPathExpressionException ex) {
        ex.printStackTrace();
        return null;
    }
}

public Document readDoc(String s)
{
    Document d = null;
    try
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputSource is = new InputSource(new StringReader(s));
        d = builder.parse(is);
    } catch (Exception e)
    {
    }
    return d;
}

}

I haven't actually tried it and you need better error handling, but it should work ok

Upvotes: 1

Related Questions