当我尝试解析XML文件时,我得到一个空节点.
XPath xPath = XPathFactory.newInstance().newXPath();
Node node = null;
try {
node = (Node) xPath.evaluate(
"/mynode",
doc,
XPathConstants.NODE);
Run Code Online (Sandbox Code Playgroud)
我仅在以下情况下面临此问题 -
1. DocumentBuilderFactory-setNameSpaceAware为true
2. DocumentBuilderFactory- setValidating 为true.
如果这些设置为false,那么我得到的结果是正确的.任何人都可以帮助我理解将这些属性设置为false的关系是什么?(我已经检查了这个问题,但这并不能说明我的疑问)
这是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>
<desc>desc goes here</desc>
<pack>my.this</pack>
<object>my.ExampleObject</object>
<properties>
<attrib>
<name>id</name>
<value>ZZZ</value>
</attrib>
<attrib>
<name>ind</name>
<value>X</value>
</attrib>
</properties>
<children>
<child>
<name>childnodename</name>
<desc>description goes here</desc>
<invalues>
<scope>ALL</scope>
</invalues>
<outvalues>
<scope>ALL</scope>
</outvalues>
<akey>
<aname>AAA</aname>
<key></key>
</akey>
<msg>
<success>code1</success>
<failure>code2</failure>
</msg>
</child>
</children>
</mynode>
Run Code Online (Sandbox Code Playgroud)
最快的解决方法是不这样做setNamespaceAware(true);:-) 但是,如果您想要一个名称空间感知的 XPath,那么您就偶然发现了一个经典问题 - XPath:有没有办法为查询设置默认名称空间?,因为 XPath 不支持默认命名空间的概念。
因此,您的 XPath 必须使用命名空间前缀,以便查询能够找到任何节点。NamespaceContext但是,您可以在XPath实例上设置 a以将命名空间前缀或默认命名空间解析为 URI。一种方法可以做到这一点,例如:
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) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当遇到带有前缀的节点时,这将解析默认名称空间(xmlns) 。http://www.example.comn
| 归档时间: |
|
| 查看次数: |
6055 次 |
| 最近记录: |