Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPathFactory not working

I'm trying to use an XPathFactory to evaluate an expression in a Java application. But I'm getting a Saxon-specific error. At one time I used Saxon for some functionality, and to do that I had to set a system property:

System.setProperty("javax.xml.xpath.XPathFactory:" + NamespaceConstant.OBJECT_MODEL_SAXON,
                "net.sf.saxon.xpath.XPathFactoryImpl");

        XPathFactory xpf = XPathFactory.newInstance(NamespaceConstant.OBJECT_MODEL_SAXON);

However, now I just want to do some XML processing using the default DOM (org.w3c.dom.Document) and process with xpath, so Saxon isn't needed. But when I try to create an XPathFactory I still get the Saxon error message:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: net/sf/saxon/lib/EnvironmentVariableResolver
    at net.sf.saxon.xpath.XPathFactoryImpl.<init>(XPathFactoryImpl.java:26)
...

I even tried "resetting" the system property:

System.setProperty("javax.xml.xpath.XPathFactory:",
                "org.apache.xpath.jaxp.XPathFactoryImpl");

            XPathFactory factory = XPathFactory.newInstance();

And

System.setProperty("javax.xml.xpath.XPathFactory:",
                    "http://java.sun.com/jaxp/xpath/dom");

                XPathFactory factory = XPathFactory.newInstance();

But that doesn't help, I still get the same error message.

How do I get rid of this in order to use the default XPathFactory again? (this has worked fine before I tried using Saxon)

like image 342
Anders Avatar asked Apr 08 '14 11:04

Anders


2 Answers

As a workaround, you can explicitly instanciate the JDK factory (or Xerces's or Saxon's).

import org.apache.xpath.jaxp.XPathFactoryImpl
// import com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl
// import net.sf.saxon.xpath.XPathFactoryImpl
...
XPathFactory factory = new XPathFactoryImpl();

If possible, prefer the real Xerces implementation to the one found in the JDK. It is more reliable.

like image 187
Valéry Avatar answered Sep 19 '22 17:09

Valéry


I have encounter the same question. Even no "System.setProperty" is called, jaxp will load saxon's xpath engine as default implementation provding saxon jar is on the classpath. Reference: namespace-unaware XPath expression fails if Saxon is on the CLASSPATH.

My solution: call saxon directly as: " XPathFactory _xFactory = new net.sf.saxon.xpath.XPathFactoryImpl();" and add jaxen-xxx.jar and xercesImpl.jar before saxon9e.jar on the classpath. Everything else remains its original state without call "System.setProperty". This works for me.

I also test another method as follows:

        System.setProperty("javax.xml.xpath.XPathFactory:" +XPathConstants.DOM_OBJECT_MODEL, "net.sf.saxon.xpath.XPathFactoryImpl");

        XPathFactory xFactory = XPathFactory.newInstance(XPathConstants.DOM_OBJECT_MODEL);

        System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME +":" + XPathFactory.DEFAULT_OBJECT_MODEL_URI, " org.apache.xpath.jaxp.XPathFactoryImpl");

        XPathFactory xFactory2 = XPathFactory.newInstance();

        System.out.println(xFactory.toString());
        System.out.println(xFactory2.toString());

The output: net.sf.saxon.xpath.XPathFactoryImpl@71623278 com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl@768b970c Since Jaxp use apache's jaxen as its default xpath implementation, this method should work tool. Since JAXP uses

like image 44
frankli22586 Avatar answered Sep 21 '22 17:09

frankli22586