我有这个xbrl.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<xbrli:xbrl xml:lang="nl" xmlns:bd-i="http://www.nltaxonomie.nl/nt15/bd/20201209/dictionary/bd-data" xmlns:link="http://www.xbrl.org/2003/linkbase" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:iso4217="http://www.xbrl.org/2003/iso4217" xmlns:xbrli="http://www.xbrl.org/2003/instance">
<link:schemaRef xlink:type="simple" xlink:href="http://www.nltaxonomie.nl/nt15/bd/20201209/entrypoints/bd-rpt-ob-aangifte-2021.xsd"/>
<xbrli:unit id="EUR">
<xbrli:measure>iso4217:EUR</xbrli:measure>
</xbrli:unit>
</xbrli:xbrl>
并且我想要得到xmlns:link属性的值。
这是我正在使用的代码:
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document xmlDocument = documentBuilder.parse("src/resources/xbrl.xml");
XPathFactory xPathFactory = XPathFactory.newInstance();
final String namespace = "http://www.xbrl.org/2003/instance";
XPath xPath = xPathFactory.newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
public String getNamespaceURI(String prefix) {
if (prefix.equals("xbrli")) {
return namespace;
} else {
return null;
}
}
public String getPrefix(String namespaceURI) {
return null;
}
public Iterator<String> getPrefixes(String namespaceURI) {
return null;
}
});
String expression = "//xmlns:xlink";
XPathExpression xPathExpression = xPath.compile(expression);
Object result = xPathExpression.evaluate(xmlDocument, XPathConstants.NODESET);
NodeList nodeList = (NodeList) result;
if (nodeList.getLength() > 0) {
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println("[" + i + "]-1-NodeValue: " + nodeList.item(i).getNodeValue());
System.out.println("[" + i + "]-2-NodeName: " + nodeList.item(i).getNodeName());
System.out.println("[" + i + "]-3-TextContent: " + nodeList.item(i).getTextContent());
System.out.println("[" + i + "]-4-LocalName: " + nodeList.item(i).getLocalName());
System.out.println("[" + i + "]-5-NamespaceURI: " + nodeList.item(i).getNamespaceURI());
}
System.out.println("Printed nodes");
} else {
System.out.println("I got nothing");
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("MESSAGE: " + ex.getMessage());
}
}
}
结果是:(
我什么都没有。
如果我试图获得XBRLfile的另一个属性的值,我可以毫无问题地获得它。但是,如果我试图获得我上面提到的价值,那么我什么都得不到。
这是我的Intellij的照片:在此处输入图像描述
为什么我不能得到属性的值?
xmlns:
属性是特殊的,因为它们声明了命名空间绑定,以便在文档中的其他地方使用。具有名称空间意识的XML处理器将自动使用这些属性,并使用它们将带前缀的元素和属性与相应的名称空间URI相关联。您可能会发现,如果将setNamespaceAware(true)
更改为setNamespaceAware(false)
,则xmlns
属性是可访问的,但我不建议您这样做。
为什么要获取该属性的值?您应该根据命名空间URI编写代码,并让您的命名空间感知XML处理器负责将命名空间前缀解析为URI。
由于XPath 3.0,您只能间接查询已使用xmlns:
声明的命名空间。
例如,要查询xmlns:xlink
声明的命名空间,可以查询使用前缀xlink:
的任何节点(元素或属性(,并从中获取命名空间(取决于处理器,这可能是一个昂贵的操作(:
distinct-values((//@xlink:*, //xlink:*)/namespace-uri())
注意:或者,直接查询命名空间节点可能仍然有效直到XPath 2.0(从那时起,命名空间轴就不再使用了(:
distinct-values(//namespace::xlink)
注意2:命名空间声明是有作用域的。在一个XML文档中,同一前缀可能有多个不同的命名空间声明。