gpt4 book ai didi

java - XPath Java 子节点计数

转载 作者:行者123 更新时间:2023-12-02 05:52:43 25 4
gpt4 key购买 nike

我想计算给定 xml 的一些子节点。但它总是返回 0,我不明白为什么。

这是 xml:

<FirstOne xmlns:xxx="http://www.w3.org/2001/XMLSchema-instance">
<Formulas xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<xxx:yyy>
<aa:bb>something</aa:bb>
<cc:dd>something</cc:dd>
</xxx:yyy>
<xxx:yyy>
<aa:bb>something</aa:bb>
<cc:dd>something</cc:dd>
</xxx:yyy>
<xxx:yyy>
<aa:bb>something</aa:bb>
<cc:dd>something</cc:dd>
</xxx:yyy>
</Formulas>

</FirstOne>

我想统计“xxx:yyy”的个数。在本例中 3.我尝试了以下方法:

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new FileInputStream(new File(fileArray[i].toString())));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
String expression;
expression = "count(//Formulas/xxx:yyy)";
Double result = (Double) xpath.evaluate(expression, doc, XPathConstants.NUMBER);

它总是给我 0.0 ...

感谢您的帮助!

最佳答案

问题都源于命名空间。

首先,XPath 评估仅在命名空间格式良好的 XML 上定义,因此您需要确保 aacc 前缀正确映射到XML。

其次,您需要使用命名空间感知解析器将XML解析为DOM树(由于我只能假设是历史原因,DocumentBuilderFactory不是命名空间-默认情况下感知)。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new FileInputStream(new File(fileArray[i].toString())));

现在您已经有了一个正确的命名空间格式正确的 DOM 树,您需要在 XPath 中正确处理命名空间。您需要定义一个 NamespaceContext 告诉 XPath 如何关联前缀和命名空间 URI。令人烦恼的是,核心 Java 库中没有可用的此接口(interface)的默认实现,但有第三方实现,例如 Spring's SimpleNamespaceContext ,或者只有三种方法,自己实现一下。使用 SimpleNamespaceContext:

XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
SimpleNamespaceContext nsCtx = new SimpleNamespaceContext();
xpath.setNamespaceContext(nsCtx);

nsCtx.bindNamespaceUri("x", "http://www.w3.org/2001/XMLSchema-instance");

有了这个上下文,您现在可以在 XPath 表达式中选择命名空间节点:

String expression = "count(//Formulas/x:yyy)";

(您使用的前缀是 NamespaceContext 中的前缀,不一定是原始 XML 源中的前缀)。

<小时/>

虽然一些 DOM 解析器和 XPath 实现可能会让您摆脱非命名空间感知的解析并忽略 XPath 表达式中的前缀,但这是一个实现细节,行为不是由规范。它可能在一个版本中工作,但在另一个版本中失败,或者如果您向项目添加其他 JAR 来更改默认解析器等,则其行为会有所不同。

关于java - XPath Java 子节点计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23409778/

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