gpt4 book ai didi

java - 当 isNameSpaceAware 和 isValidating 为 "Node"时,XPath 为 "true"返回 null

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:31:04 27 4
gpt4 key购买 nike

当我尝试解析 XML 文件时得到一个空节点。

XPath xPath = XPathFactory.newInstance().newXPath();
Node node = null;
try {
node = (Node) xPath.evaluate(
"/mynode",
doc,
XPathConstants.NODE);

我遇到这个问题只是为了以防万一-
1. DocumentBuilderFactory- setNameSpaceAware 为真
2. DocumentBuilderFactory- setValidating 为真。

如果这些设置为 false,那么我会得到正确的结果。谁能帮助我理解将这些属性设置为 false 的关系是什么?(我查了this问题,但并没有消除我的疑惑)

这是 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>

最佳答案

最快的解决方法是不执行 setNamespaceAware(true); :-) 但是,如果您想要命名空间感知 XPath,那么您会遇到一个经典问题 - XPath: Is there a way to set a default namespace for queries? ,因为 XPath 不支持默认命名空间的概念。

因此,您的 XPath 必须使用 namespace 前缀才能让查询找到任何节点。但是,您可以设置 NamespaceContextXPath 上将命名空间前缀或默认命名空间解析为 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) {

}
}
}

因此,当节点带有 n 前缀时,这会将默认命名空间 (xmlns) 解析为 http://www.example.com遇到了。

关于java - 当 isNameSpaceAware 和 isValidating 为 "Node"时,XPath 为 "true"返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6760343/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com