【问题标题】:Return first value after if statement is trueif 语句为真后返回第一个值
【发布时间】:2015-03-02 08:10:58
【问题描述】:

我有以下 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 字符串,然后从 &lt;Name&gt; 元素返回值。我创建了执行此操作的 xquery,但它返回两个值,因为该语句对于两个节点都是正确的。 当然这只是一个示例 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语句为真时中断循环?

【问题讨论】:

    标签: xml xquery


    【解决方案1】:

    您可以将返回的结果限制在第一个节点:

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

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

    【讨论】:

    • +1,但[position() = 1]可以缩短为[1]
    • 绝对正确。我选择了详细的语法,因为它可以更容易地适应范围测试。
    【解决方案2】:

    您只需过滤第一个结果:

    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' 的情况。

    【讨论】:

      猜你喜欢
      • 2014-09-07
      • 1970-01-01
      • 2021-03-04
      • 2022-01-03
      • 2018-05-07
      • 2020-09-19
      • 2021-02-26
      • 2014-03-07
      • 1970-01-01
      相关资源
      最近更新 更多