2015-03-02 3 views
1

я следующий 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> элемента. Я создал 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) 

Есть ли способ, например, разорвать петлю, когда, если утверждение верно?

ответ

2

Вы можете ограничить возвращаемые результаты первого узла:

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

Это решение может выглядеть дорого, на первый взгляд, но многие остановки реализации XQuery цикла, как только первый результат был найден.

+0

+1, но '[position() = 1]' можно укоротить до '[1]' – dirkk

+0

Абсолютно верно. Я выбрал подробный синтаксис, потому что его легче настроить на тесты диапазона. –

1

Вы просто фильтр для первого результата:

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'.

Смежные вопросы