我正试图从这里得到一份名单 - 但它只是让我回归“真实” - 我做错了什么?
for $x in /Book
where $x//Occupation/text()="Builder" and $x//Sex/text()="M"
return $x//Name/text() and $x//LastName/text()
我哪里错了?
XML示例: `.....
<Person>
<Name>Mathew</Name>
<LastName>Michaels</LastName>
<Relation>Father</Relation>
<Religion>Roman Catholic</Religion>
<Education>Read</Education>
<Age>83</Age>
<Sex>M</Sex>
<Occupation>Builder</Occupation>
<Maried>Widower</Maried>
<PlaceOfBirth>Co. Kildare</PlaceOfBirth>
</Person> `
答案 0 :(得分:3)
您正在返回布尔值(true或false),因为您正在使用布尔表达式(X and Y
)。如果要返回两个节点序列的并集,请改为使用管道符号(X | Y
),或者如果需要X之前的序列,请使用逗号(X,Y
)。或者,如果要返回两个字符串的串联,请使用concat()
函数(如下面的示例所示)。
我想也许你并不理解&#34;对于&#34;表达工作。 $ x变量绑定到&#34; in
&#34;之后的表达式返回的任何节点序列。因此,在您的情况下,$ x绑定到一个<Book>
元素(或者,根据您的XQuery实现,可能是数据库中的所有<Book>
个文档元素)。由于$ x绑定到<Book>
,这意味着您的查询基本上是这样说的(如果您首先进行上述更正,则替换&#34;以及&#34;使用&#34; |&#34;): &#34;如果此<Book>
文档中包含任何<Occupation>
元素&#34; Builder&#34;以及带有&#34; M&#34;的所有<Sex>
个元素,然后返回所有<Book>
个文档的<Name>
和<LastName>
文本节点子节点。
所以看起来你真正想要的是将$ x绑定到<Person>
元素(假设<Person>
显示为<Book>
的子元素,而您的示例XML并没有这样做。 t指定):
for $x in /Book/Person
where $x/Occupation eq "Builder" and $x/Sex eq "M"
return concat($x/Name,' ',$x/LastName)
注意我做了一些改动。我删除了&#34; //&#34;赞成&#34; /&#34;,因为您的示例XML显示<Occupation>
,<Sex>
,<Name>
和<LastName>
是{{1}的子项}。只使用&#34; //&#34;如果你不知道元素可能出现在哪里(n级深),原因有两个:
我还添加了concat()函数,因为我怀疑它接近你试图提取的内容。
我还摆脱了<Person>
节点测试。一般来说,你不需要它们(并且应该避免它们)。你真正想要做的是比较每个元素的字符串值,而不是每个文本节点子元素的字符串值。您可能知道每个元素只有一个文本节点子节点,但是没有理由编写在这种情况下会破坏的代码:
text()
或
<Religion>Roman <!--comment-->Catholic</Religion>
我也替换了#34; =&#34;与&#34; eq&#34;,因为&#34; =&#34;用于比较可能的多个序列和&#34; eq&#34;仅用于比较奇异序列。
最后,你甚至不需要这个用例的FLWOR表达式。您也可以将其写为路径表达式:
<PlaceOfBirth><b>Co.</b> Kildare</PlaceOfBirth>
答案 1 :(得分:2)
“和”是一个布尔运算符 - 结果始终为true或false。在英语中我们可能会使用“和”来获得两组的联合(“给我书中的作者和标题”),在逻辑'和'中总是结合两个布尔(如果作者和作者同时author and title
是真的。标题存在)。所以你的“and”运算符需要被一个“union”运算符替换,或者其他结合了结果的东西,比如concat()或“,”。
另一个问题是运营商优先级。通常,如果return子句包含任何非平凡的表达式,那么将parens放在它周围是最安全的。你想要
for $x in X return (a, b)
不
(for $x in X return a), b
答案 2 :(得分:0)
“return”子句之后指定的表达式在逻辑操作中组合,该操作始终返回true
或false
。以下两个版本可能会做你想要的:
for $x in /Book
where $x//Person/text()="Builder" and $x//Place/text()="F"
return ($x//Name/text(), $x//LastName/text())
for $x in /Book
where $x//Person/text()="Builder" and $x//Place/text()="F"
return ($x//Name/text() | $x//LastName/text())