Java 无法计算XPath中的表达式
一,;我使用XPath解析URL返回的XML文档,当我使用给定的输入运行代码时,它可以工作,但当将输入作为用户输入时,它抛出异常。 代码:Java 无法计算XPath中的表达式,java,xml,exception,xpath,transformer,Java,Xml,Exception,Xpath,Transformer,一,;我使用XPath解析URL返回的XML文档,当我使用给定的输入运行代码时,它可以工作,但当将输入作为用户输入时,它抛出异常。 代码: class{ private String generalQuery = "//@*"; method(){ System.out.println("Enter URL"); url = scan.nextLine(); URL oracle = new URL(url);
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;
}
}
javax.xml.transform.TransformerException: Unable to evaluate expression using this context
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;
}
}
类名称空间:
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;
}
}
javax.xml.transform.TransformerException: Unable to evaluate expression using this context
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;
}
}
import java.util.Iterator;
导入javax.xml.xmlstants;
导入javax.xml.namespace.NamespaceContext;
导入org.w3c.dom.Document;
公共类名称空间实现名称空间上下文{
私人文件来源文件;
公共名称空间(文档){
sourceDocument=文档;
}
@凌驾
公共字符串getNamespaceURI(字符串前缀){
if(前缀.equals(XMLConstants.DEFAULT\u NS\u前缀)){
返回sourceDocument.lookupNamespaceURI(null);
}否则{
返回sourceDocument.lookupNamespaceURI(前缀);
}
}
@凌驾
公共字符串getPrefix(字符串名称空间URI){
返回sourceDocument.lookupPrefix(namespaceURI);
}
@凌驾
公共迭代器getPrefixes(字符串名称空间URI){
返回null;
}
}
您似乎缺少一个可以自己实现的名称空间上下文
另请参见此线程:
例如:
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;
}
}
然后启动XPath实例,如下所示:
getXPath().setNamespaceContext(new NamespaceResolver(doc));
尝试计算XPath表达式时,null
文档也可能导致异常“无法使用此上下文计算表达式”。(我也有同样的错误,我花了一段时间才发现我没有正确初始化文档)
在您的代码中
try {
// load document
}
catch (Exception ex) {
System.err.println("unable to load XML: " + ex);
}
// happily continue
这是自找麻烦。如果在初始化期间发生异常,则应立即停止,而不应继续。如果您完全不知道如何处理错误,请使用catch(Exception e){throw new error(e);}
。这将导致异常冒泡,并有望由打印堆栈跟踪并退出的默认异常处理程序处理
作为你问题的读者,我甚至不知道异常是从哪里抛出的。你应该提供这些信息。注意,您还可以使用someException.printStackTrace()
获取指向正确行的堆栈跟踪。在我的例子中,这不是由于null
文档,而是由于没有根元素的空文档。添加后者解决了问题。此代码段中的doc
类型是什么?它是由DOM创建的XML文档名称空间是什么
?setNamespaceContext
方法需要类型为NamespaceContext
的参数。正如@Ian所指出的,您也没有告诉我们doc
的类型。如前所述,你的问题甚至无法编译,你让我们猜测你应该包含的内容。我用你可能需要的所有信息编辑了问题。这可能是对的,但OP没有包含足够的信息来确定。我已经做到了,something是类NameSpaceResolver的名称,在我的code@Brass布洛克:也许你也可以给我们看看XML。xml是否有正确的名称空间声明?是的,在我的例子中,错误是由空文档引起的。这是上游错误的结果。谢谢