2015-03-02 80 views
1

我有以下XML:返回第一個值if語句後真

<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 2015-03-02 09:52:54

+0

絕對如此。我選擇了詳細的語法,因爲它可以更容易地進行範圍測試調整。 – 2015-03-02 11:03:58

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