Return if 语句后的第一个值为真

Return first value after if statement is true

我关注xml:

<test>
    <TestStruktur>
        <TestReference>ID_text_random_uuid</TestReference>
        <TestReference>ID_test_random_uuid</TestReference>
        <Name>Some name</Name>
    </TestStruktur>
    <TestStruktur>
        <TestReference>ID_test_random_uuid</TestReference>
        <TestReference>ID_text_random_uuid</TestReference>
        <Name>Some name</Name>
    </TestStruktur>
</test>

我需要搜索 TestReference 元素并检查值是否包含 test 字符串,然后检查 <Name> 元素中的 return 值。我已经创建了执行此操作的 xquery,但它 return 有两个值,因为该语句对两个节点都是正确的。 当然这只是一个例子xml。我可以有很多 TestStruktur 个节点甚至更多 TestReference 个节点

这是我的 xquery:

declare function local:test($doc as node()) as xs:string {
    for $test2 in $doc//test/TestStruktur
        for $test in $test2/TestReference
        return
            if(contains($test, 'test')) then 
                data($test2/Name)
            else ()
};

for $doc in collection('Testing')
return local:test($doc)

有什么方法可以在 if 语句为真时中断循环吗?

您可以限制返回结果到第一个节点:

(for $test2 in $doc//test/TestStruktur
 for $test in $test2/TestReference
 where contains($test, 'test')
 return data($test2/Name)
)[position() = 1]

这个解决方案乍一看可能很昂贵,但很多 XQuery 实现在找到第一个结果后就停止循环。

您只需过滤第一个结果:

declare function local:test($doc as node()) as xs:string {
  (
    for $test2 in $doc//test/TestStruktur
        for $test in $test2/TestReference
        return
            if(contains($test, 'test')) then 
                data($test2/Name)
            else ()
  )[1]
};

谓词可能是量词的格:

declare function local:test($doc as node()) as xs:string
{
  (
    for $test2 in $doc//test/TestStruktur
    where some $test in $test2/TestReference satisfies contains($test, 'test')
    return $test2/Name
  )
  [1]
};

但它也可以在单个路径表达式中完成:

declare function local:test($doc as node()) as xs:string
{
  ($doc//test/TestStruktur[TestReference[contains(., 'test')]]/Name)[1]
};

以上都是等价的。请注意,结果类型可能最好是 xs:string?,以提供未找到 'test' 的情况。