你,因爲你使用的是布爾表達式(X and Y
)返回一個布爾值(true或false)。如果要返回兩個節點序列的並集,請改用管道符號(X | Y
),或者如果您想要X在Y之前的序列,請使用逗號(X,Y
)。或者如果你想返回兩個字符串的連接,使用concat()
函數(如下面的例子)。
我想也許你不瞭解「for」表達式是如何工作的。 $ x變量綁定到「in
」之後的表達式返回的任何節點序列。所以在你的情況下,$ x綁定到一個<Book>
元素(或者,根據你的XQuery實現,可能是數據庫中的所有<Book>
文檔元素)。由於$ x綁定到<Book>
,這意味着您的查詢基本上是這樣說的(如果您首先進行上述更正,則將「and」替換爲「|」):「如果此<Book>
文檔具有帶」Builder「的任何<Occupation>
元素<Sex>
元素與「M」,然後返回所有<Book>
文檔的<Name>
和<LastName>
文本節點孩子。
所以它看起來像你真正想要的是給$ x綁定到<Person>
元素,而不是(假設<Person>
出現的孩子<Book>
,您的示例XML未指定):
for $x in /Book/Person
where $x/Occupation eq "Builder" and $x/Sex eq "M"
return concat($x/Name,' ',$x/LastName)
注意我做了一些更改。我刪除了「//」以支持「/」,因爲您的示例XML顯示<Occupation>
,<Sex>
,<Name>
和<LastName>
是<Person>
的子項。只能用「//」,如果你不知道在哪裏的元素可能會出現(正層次深),原因有二:
- 「//」比「/」慢,因爲這意味着中的XQuery引擎必須搜索更多的地方,並且
- 你的代碼暗示了錯誤的東西:這些元素可能以後代的形式出現(並且不一定總是作爲直接的孩子出現)。
我還添加了concat()函數,因爲我懷疑它接近你想要提取的東西。
我也擺脫了text()
節點測試。一般來說,你不需要它們(並且應該避免它們)。你真正想要做的是比較每個元素的字符串值,而不是每個文本節點子元素的字符串值。你可能知道,每一個元素只會有一個文本節點孩子,但沒有理由編寫的代碼,將在情況下打破這樣的:
<Religion>Roman <!--comment-->Catholic</Religion>
或
<PlaceOfBirth><b>Co.</b> Kildare</PlaceOfBirth>
我也改爲「=」與「eq」相關,因爲「=」用於比較可能的多個序列,而「eq」僅用於比較單數序列。
最後,您甚至不需要此用例的FLWOR表達式。你也可以把它寫成一個路徑表達式:
/Book/Person[Occupation eq "Builder"][Sex eq "M"]/concat(Name,' ',LastName)
我已經計算出東西是給我更喜歡我需要的答案的格式,但仍然沒有正確的答案 - '讓$一個:= /文檔//職業/ text()='Builder' let $ b:=/Document // Sex/text()='M' return(// Name)|(// LastName)' – nevermind
如果你想返回對''和''元素,這裏是我的答案結尾處的路徑表達式的修改版本:'/ Book/Person [職業等式Builder]] [S ex eq「M」] /(Name,LastName)' –
請注意,上面的註釋中的示例將$ a和$ b綁定到布爾值,這可能不是您想要的。這就像是說:「如果有任何''元素具有'生成器文本節點子元素',讓$ a爲真。 –