java - JAXP XPath 1.0 或 2.0 - 如何区分空字符串和不存在的值

标签 java xpath xpath-2.0 jaxp

给定以下 XML 实例:

<entities>
    <person><name>Jack</name></person>
    <person><name></name></person>
    <person></person>
</entities>

我使用以下代码来:(a) 迭代人员并 (b) 获取每个人的姓名:

XPathExpression expr = xpath.compile("/entities/person");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0 ; i < nodes.getLength() ; i++) {
    Node node = nodes.item(i);
    String innerXPath = "name/text()";
    String name  = xpath.compile(innerXPath).evaluate(node);
    System.out.printf("%2d -> name is %s.\n", i, name);
}

上面的代码无法区分第二人称情况(名称为空字符串)和第三人称情况(根本没有名称元素),只是打印:

0 -> name is Jack.
1 -> name is .
2 -> name is .

有没有办法使用不同的 innerXPath 表达式来区分这两种情况?在 this SO question看起来 XPath 方式将返回一个空列表,但我也尝试过:

String innerXPath = "if (name) then name/text() else ()";

...并且输出仍然相同。

那么,有没有办法用不同的 innerXPath 表达式来区分这两种情况?我的类路径上有 Saxon HE,因此我也可以使用 XPath 2.0 功能。

更新

因此,根据已接受的答案,我能做的最好的事情如下:

XPathExpression expr = xpath.compile("/entities/person");                                                                                                                                                                                 
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);                                                                                                                                                                   
for (int i = 0 ; i < nodes.getLength() ; i++) {                                                                                                                                                                                           
    Node node = nodes.item(i);                                                                                                                                                                                                            
    String innerXPath = "name";                                                                                                                                                                                                           
    NodeList names = (NodeList) xpath.compile(innerXPath).evaluate(node, XPathConstants.NODESET);                                                                                                                                         
    String nameValue = null;                                                                                                                                                                                                              
    if (names.getLength()>1) throw new RuntimeException("impossible");                                                                                                                                                                    
    if (names.getLength()==1)                                                                                                                                                                                                             
        nameValue = names.item(0).getFirstChild()==null?"":names.item(0).getFirstChild().getNodeValue();                                                                                                                                  
    System.out.printf("%2d -> name is [%s]\n", i, nameValue);                                                                                                                                                                             
} 

上面的代码打印:

0 -> name is [Jack]
1 -> name is []
2 -> name is [null]

在我看来,这并不是很令人满意,因为逻辑在 XPathJava 代码中传播,并且限制了 XPath 作为主机语言和与 API 无关的表示法。我的特定用例是仅将 XPath 集合保存在属性文件中并在运行时评估它们,以便获取我需要的信息,而无需任何临时的额外处理。显然这是不可能的。

最佳答案

基于 XPath 1.0 的 JAXP API 在这方面非常有限。我的直觉是返回 Name 元素(作为 NodeList)。因此所需的 XPath 表达式只是“Name”。那么情况 1 和 2 将返回长度为 1 的节点列表,而情况 3 将返回长度为 0 的节点列表。通过获取节点的值并测试它是否为零,可以在应用程序中轻松地区分情况 1 和 2。长度。

无论如何,最好避免使用/text(),因为它会导致您的查询对 XML 中是否存在注释很敏感。

关于java - JAXP XPath 1.0 或 2.0 - 如何区分空字符串和不存在的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17390684/

相关文章:

javascript - 如何使用 Selenium x-path 查找包含单词 "download"的所有元素?

java - XPath 中的循环?

XPath 2.0 : how to select the current node - current() no longer available

java - 基于动态正则表达式的 XPath 搜索

java - 搜索字符串,然后使用 Selenium 单击父 DIV

Java - 只读取文件的第一行

fxml 上的 JavaFX TextField 宽度不同

xpath - 使用Java在DOM4j中解析具有自己命名空间的子节点

java - 将元素添加到 ArrayList 或 ArrayAdapter 中的特定索引

sql - SUM 和 COUNT xPath 表达式在 Oracle 11.2 中不起作用