java 无法计算 XPath 中的表达式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16648357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unable to evaluate expression in XPath
提问by Muhammed Refaat
I;m using XPath to parse XML document returned by a URL, when i run my code with given inputs it works but when giving it inputs as a user input it throws an exception. The Code:
我正在使用 XPath 解析由 URL 返回的 XML 文档,当我使用给定的输入运行我的代码时,它可以工作,但是当将输入作为用户输入提供时,它会引发异常。 代码:
class{
private String generalQuery = "//@*";
method(){
System.out.println("Enter URL");
url = scan.nextLine();
URL oracle = new URL(url);
InputStream is = oracle.openStream();
org.w3c.dom.Document doc = null;
DocumentBuilderFactory domFactory;
DocumentBuilder builder;
try {
domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
builder = domFactory.newDocumentBuilder();
doc = builder.parse(is);
} catch (Exception ex) {
System.err.println("unable to load XML: " + ex);
}
Map <String, String> params = new HashMap<String, String> ();
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.setNamespaceContext(new NameSpaces(doc));
XPathExpression expr = xpath.compile(generalQuery);
Object result = expr.evaluate(doc, XPathConstants.NODESET); // exception thrown here
NodeList nl = (NodeList) result;
for (int i = 0 ; i < nl.getLength() ; i++){
Node n = (Node)nl.item(i);
params.put(n.getNodeName(), n.getNodeValue());
}
return params;
}
}
The Exception:
例外:
javax.xml.transform.TransformerException: Unable to evaluate expression using this context
The class NameSpaces :
类 NameSpaces :
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import org.w3c.dom.Document;
public class NameSpaces implements NamespaceContext {
private Document sourceDocument;
public NameSpaces(Document document) {
sourceDocument = document;
}
@Override
public String getNamespaceURI(String prefix) {
if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
return sourceDocument.lookupNamespaceURI(null);
} else {
return sourceDocument.lookupNamespaceURI(prefix);
}
}
@Override
public String getPrefix(String namespaceURI) {
return sourceDocument.lookupPrefix(namespaceURI);
}
@Override
public Iterator<String> getPrefixes(String namespaceURI) {
return null;
}
}
回答by yankee
The exception "Unable to evaluate expression using this context" may also result from a null
document when trying to evaluate an XPath expression. (I had the same error and it took me a while to figure out I did not initialize my document properly).
null
尝试计算 XPath 表达式时,文档也可能会导致“无法使用此上下文计算表达式”异常。(我遇到了同样的错误,我花了一段时间才发现我没有正确初始化我的文档)。
In your code you have
在你的代码中,你有
try {
// load document
}
catch (Exception ex) {
System.err.println("unable to load XML: " + ex);
}
// happily continue
This is a call for trouble. If an exception happens during initialization you should STOP right there and you should not continue. If you have absolutely no idea how to handle the error, use catch(Exception e) { throw new Error(e); }
. This will cause exceptions to bubble up and hopefully be handled by the default exception handler which prints a stack trace and exits.
这是自找麻烦。如果在初始化期间发生异常,您应该立即停止并且不应该继续。如果您完全不知道如何处理错误,请使用catch(Exception e) { throw new Error(e); }
. 这将导致异常冒泡,并希望由打印堆栈跟踪并退出的默认异常处理程序处理。
As the reader of your question I don't even know where the exception was thrown. You should provide this information. Note that you can also use someException.printStackTrace();
to get the stack trace which points you to the correct line.
作为您问题的读者,我什至不知道在哪里抛出异常。您应该提供这些信息。请注意,您还可以使用someException.printStackTrace();
获取指向正确行的堆栈跟踪。
回答by User0
What you seem to be missing is a NameSpaceContext
that you can implement yourself.
您似乎缺少的是NameSpaceContext
您可以自己实现的。
Also see this thread: NamespaceContext and using namespaces with XPath
另请参阅此线程:NamespaceContext and using namespaces with XPath
Example:
例子:
class NamespaceResolver implements NamespaceContext {
private final Document document;
public NamespaceResolver(Document document) {
this.document = document;
}
public String getNamespaceURI(String prefix) {
if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
return document.lookupNamespaceURI(null);
} else {
return document.lookupNamespaceURI(prefix);
}
}
public String getPrefix(String namespaceURI) {
return document.lookupPrefix(namespaceURI);
}
@SuppressWarnings("rawtypes")
public Iterator getPrefixes(String namespaceURI) {
// not implemented
return null;
}
}
Then you initiate the XPath instance like this:
然后像这样启动 XPath 实例:
getXPath().setNamespaceContext(new NamespaceResolver(doc));
回答by Monkey Supersonic
In my case this was not due to a null
document, but due to an emptydocument with no root element. Appending the latter solved the issue.
在我的情况下,这不是由于null
文档,而是由于没有根元素的空文档。附加后者解决了这个问题。