为什么getLocalName()返回null?

10

我正在加载像这样的一些XML字符串:

Document doc = getDocumentBuilder().parse(new InputSource(new StringReader(xml)));

接下来,我从这个文档中提取一个节点:

XPath xpath = getXPathFactory().newXPath();
XPathExpression expr = xpath.compile(expressionXPATH);
NodeList nodeList = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);

Node node = nodeList.item(0);

现在我想获取此节点的本地名称,但我得到了null

node.getLocalName(); // return null

通过调试器,我发现我的节点具有以下类型:DOCUMENT_POSITION_DISCONNECTED

Javadoc指出对于这种类型的节点,getLocalName()返回null

  • 为什么节点的类型是DOCUMENT_POSITION_DISCONNECTED而不是ELEMENT_NODE?
  • 如何“转换”节点的类型?

1
能否提供一个最小但完整的示例,让我们能够重现这个问题?请展示 xmlexpressionXPATH - Martin Honnen
你是否使用过命名空间感知的 DocumentBuilderFactory - Martin Honnen
至少要展示你正在使用的XPath表达式。 - VGR
1个回答

16

根据文档说明

对于使用DOM Level 1方法创建的节点,[...]其值始终为null。

因此,请确保使用启用命名空间支持的DocumentBuilderFactorysetNamespaceAware(true)方法,这样DOM将支持命名空间感知的DOM Level 2/3,并且getLocalName()将具有非空值。

以下是一个简单的测试程序:

    String xml = "<root/>";

    DocumentBuilderFactory db = DocumentBuilderFactory.newInstance();

    Document dom1 = db.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));

    System.out.println(dom1.getDocumentElement().getLocalName() == null);

    db.setNamespaceAware(true);

    Document dom2 = db.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));

    System.out.println(dom2.getDocumentElement().getLocalName() == null);

输出

true
false

所以(至少)您遇到的本地名称问题是由于使用了不支持命名空间的DOM Level 1文档(生成器工厂)。


如何知道正在使用哪个DOM级别? - Stephan
1
如果您想查询现有的实现,需要查看 https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/DOMImplementation.html#hasFeature(java.lang.String,%20java.lang.String) 来测试各种支持的功能。但我不完全确定它有多精确,我只知道对于有意义的 XPath 使用,命名空间感知 DOM 是必不可少的。 - Martin Honnen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接