首页 > 解决方案 > XPath 验证元素是否不存在或不包含所需的值

问题描述

我想报告缺少某个元素或如果存在不包含所需值的问题。

我的初始状态存在但不包含所需文本时工作正常:

xmllint ./myfiles*/*.xml --xpath "//descendant-or-self::node()[local-name(.) = 'personName' and not(text() = 'novice')]"

我如何还包括标签缺失整个情况的情况?

这是我的尝试,但不起作用:

xmllint ./myfiles*/*.xml --xpath "not(//descendant-or-self::node()[local-name(.) = 'personName' and not(text() = 'personName')]) or (//descendant-or-self::node()[local-name(.) = 'personName' and not(text() = 'novice')])"

高级 XML

<com.mycompany.MyTestClass>
    <id>12312312</id>
    <uberclass>
        .. more xml here
    </uberclass>
    <personAge>11</personAge>
    .. more xml here
    <personName>novice</personName>
    ...more xml here
</com.mycompany.MyTestClass>

标签: xmlxpath

解决方案


not(X='value')如果 X 选择的节点集不包含字符串值等于 的节点,则表达式返回 true value。这包括 X 选择的节点集为空的情况,即节点不存在的情况。

现在的问题是,你希望你的表达式返回什么?如果您希望它返回相关元素(如果存在并具有所需的值),否则返回空节点集,那么您可以简单地编写

//personName[. = 'novice']

如果你想返回一个布尔值来告诉你是否存在这样的节点,你可以写

boolean(//personName[. = 'novice'])

实际上,您可以将其缩短为

//personName = 'novice'

虽然我个人觉得这不太清楚,它的缺点是你不能将相同的收缩应用于更复杂的谓词,比如

//personName[starts-with(., 'novice')]

如果你想要相反(如果元素不存在或没有正确的值,则返回 true),然后

not(//personName[. = 'novice'])

推荐阅读