提问者:小点点

Xpath:检查节点是否不存在


我从我的网络商店API调用中获取XML,其结构非常像下面的示例:

<Customers>
<Customer>
    <Username>userOne</Username>
    <Params>
        <Param>
            <Id>111</Id>
            <Name>Param1</Name>
            <Value><![CDATA[Param 1 is on]]></Value>
        </Param>
        <Param>
            <Id>112</Id>
            <Name>Param2</Name>
            <Value><![CDATA[OFF]]></Value>
        </Param>
    </Params>
</Customer>
<Customer>
    <Username>userTwo</Username>
    <Params>
        <Param>
            <Id>111</Id>
            <Name>Param1</Name>
            <Value><![CDATA[Param 1 is on]]></Value>
        </Param>
        <Param>
            <Id>112</Id>
            <Name>Param2</Name>
            <Value><![CDATA[OFF]]></Value>
        </Param>
    </Params>
</Customer>
<Customer>
    <Username>userThree</Username>
    <Params>            
        <Param>
            <Id>112</Id>
            <Name>Param2</Name>
            <Value><![CDATA[ON]]></Value>
        </Param>
    </Params>
</Customer>

其中有更多的参数,数量取决于许多外部因素。我正在尝试获取用户名,当id“111”和id“112”的值是我要查找的值时Customers/Customer[Params/Param[Id/text()='111']/Value/text()='Param 1打开][Params/Param[Id/text()='112']/Value/text()='OFF']/Username/text()

上述代码按预期返回“userOne”和“userTwo”。

问题是,Id“111”要么有值“Param 1 is on”要么什么都没有,如果没有值,它就不会显示在XML中。所以我需要一个表达式来检查id为“111”的节点是否不存在,id为“112”的值是否为“ON”。

不幸的是,Xpath对我来说真的很新,我无法找到一种方法来具体检查节点是否不存在。


共2个答案

匿名用户

根据定义,当强制转换为布尔值时,节点集为true,并且只有当它包含元素时才为true(https://www.w3.org/TR/xpath-31/#dt-ebv)。这样,值元素的存在性检查可以如下所示

fn:boolean(Customers/Customer[Params/Param[Id/text()='111']/Value)

或者如果你想把它作为第三种选择包括在你的支票里

Customers/Customer[Params/Param[Id/text()='111' and not ./Value]

匿名用户

XPathcount(expr)可用于检查是否存在条件

Customers/Customer[count(Params/Param[Id/text()='111' and Value/text()='Param 1 is on']) = 0 and Params/Param[Id/text()='112']/Value/text()='ON']/Username/text()

因此,这一部分检查该节点是否不存在计数(Params/Param[Id/text()='111'和Value/text()='Param 1在'])=0
或计数(Params/Param[Id/text()='111')=0

并且这部分检查其他预期条件
Params/Param[Id/text()='112']/Value/text()='ON'

应用于样本返回:
userThree