更新时间:2023-11-30 23:24:46
最快的解决方法是不执行 setNamespaceAware(true);
:-)但是,如果您希望使用名称空间的XPath,则可以偶然发现了一个经典问题-
The quickest fix is to not do setNamespaceAware(true);
:-) However, if you want a namespace aware XPath then you have stumbled across a classic problem - XPath: Is there a way to set a default namespace for queries?, in that XPath does not support the concept of a default namespace.
因此,您的XPath必须使用名称空间前缀才能使查询找到任何节点.但是,您可以设置 NamespaceContext
在
So your XPath must use a namespace prefix in order for the query to find any nodes. However, you can set a NamespaceContext
on the XPath instance to resolve the namespace prefix or default namespace to a URI. One way to do this, for example:
import java.util.*;
import java.io.ByteArrayInputStream;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
public class XmlParse {
public static void main(String[] args) throws Exception {
String xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<mynode xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.example.com\" xsi:schemaLocation=\"http://www.example.com example.xsd\">" +
"<name>TargetName</name>" +
"</mynode>";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
final String nonameNamespace = doc.getFirstChild().getNamespaceURI();
NamespaceContext ctx = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
String uri = null;
if (prefix.equals("n")) {
uri = nonameNamespace;
}
return uri;
}
@Override
public Iterator getPrefixes(String val) {
throw new IllegalAccessError("Not implemented!");
}
@Override
public String getPrefix(String uri) {
throw new IllegalAccessError("Not implemented!");
}
};
XPath xPath = XPathFactory.newInstance().newXPath();
xPath.setNamespaceContext(ctx);
Node node = null;
try {
node = (Node) xPath.evaluate("/n:mynode/n:name", doc, XPathConstants.NODE);
System.out.println(node.getNodeName());
System.out.println(node.getFirstChild().getNodeValue());
} catch (Exception e) {
}
}
}
因此,当前缀为 n
的节点将默认名称空间( xmlns
)解析为 http://www.example.com
遇到.
So this will resolve the default namespace (xmlns
) to http://www.example.com
when a node with n
prefix is encountered.