考虑以下XML:
<bib>
<book year="1994">
<title>TCP/IP Illustrated</title>
<author><last>Stevens</last><first>W.</first></author>
<publisher>Addison-Wesley</publisher>
<price>65.95</price>
</book>
<book year="2000">
<title>Data on the Web</title>
<author><last>Abiteboul</last><first>Serge</first></author>
<author><last>Buneman</last><first>Peter</first></author>
<author><last>Suciu</last><first>Dan</first></author>
<publisher>Morgan Kaufmann Publishers</publisher>
<price>39.95</price>
</book>
<book year="1999">
<title>The Economics of Technology and Content for Digital TV</title>
<editor><last>Gerbarg</last><first>Darcy</first><affiliation>CITI</affiliation></editor>
<publisher>Kluwer Academic Publishers</publisher>
<price>129.95</price>
</book>
</bib>
我知道以下XQuery查询
for $book in doc(“books.xml”)//book
where $book/price>60
return <expensiveBook>
{ $book/title/text() }
</expensiveBook>
将完全返回两本书的标题,价格大于60:
<expensiveBook>TCP/IP Illustrated</expensiveBook>
<expensiveBook>The Economics of Technology and Content for Digital TV</expensiveBook>
而是以下查询:
let $books := doc(“books.xml”)//book
where $books/price > 60 (: existential... :)
return <expensiveBooks>
{ $books/title }
</expensiveBooks>
将返回XML doc中的全部三本书:
<expensiveBooks>
<title>TCP/IP Illustrated</title>
<title>Data on the Web</title>
<title>The Economics of Technology and Content for Digital TV</title>
</expensiveBooks>
我无法理解为什么会发生这种情况,我不应该将整本书放入用“let”声明的变量中,然后用where子句过滤它吗?为什么它还返回“网上数据”一书,哪个价格低于60?
我无法理解的另一个奇怪的事情是像下面这样的查询:
let $books in doc(“books.xml”)//book[price>60]
return <expensiveBook>
{ $books/title }
</expensiveBook>
正确地只返回价格大于60的两本书:
<expensiveBooks>
<title>TCP/IP Illustrated</title>
<title>The Economics of Technology and Content for Digital TV</title>
</expensiveBooks>
这里有什么用?为什么这种行为不符合我的预期呢? where子句对let和for子句的工作方式是否有所不同?那么最后一个查询呢,使用“let”子句但是通过XPath语法指定price元素[element = value]?
感谢您的帮助,一如既往:)
答案 0 :(得分:1)
我认为您需要在XPath和XQuery上找到一些基本资源。 当你说:
let $books := doc(“books.xml”)//book
where $books/price > 60 (: existential... :)
return <expensiveBooks>
{ $books/title }
</expensiveBooks>
这意味着:将$ books绑定到所有书元素的序列,现在考虑序列中书籍的所有价格元素的顺序:如果它们中的任何一个超过60,则返回所有标题元素的序列$ books中的任何书元素,包含在元素中。所以你得到全部或全部。
你的第一个查询说:迭代这一系列的书元素,如果我现在拥有的价格超过60,则返回标题。
带有XPath约束的查询:
let $books in doc(“books.xml”)//book[price>60]
return <expensiveBook>
{ $books/title }
</expensiveBook>
说:构造一个所有书元素的序列,其元素子元素超过60,并返回一个由这些书的所有标题序列组成的元素,包含在元素中。
让我们绑定一个变量;用于依次将变量绑定到序列的每个成员。序列上的路径表达产生其他序列。 '='和'&gt;'是对序列进行操作并返回单个布尔结果的存在运算符。
答案 1 :(得分:1)
FLWOR表达式的逻辑是它表示元组流,其中元组是(变量名,值)对。 let子句创建一个元组:一个变量,一个值。 for子句创建元组流,为选择中的每个项创建一个元组。 where子句过滤元组流,因此只保留满足条件的那些元组。
如果只有一个元组开始,则使用&#34;过滤&#34;只能是一个元组或没有元组。
答案 2 :(得分:0)
这是因为您没有对序列$books
应用约束。这基本上就是如何评估逻辑:Where any book has a price greater than 60, return all books
。正如您已经发现的那样,您需要使用XPath谓词来约束序列,或者在XQuery where
迭代器中使用for
进行约束。
答案 3 :(得分:0)
可能是要使用“ for”而不是“ let”?
使用“ let”,输出如下所述:
输出:
<expensiveBooks>
<title>TCP/IP Illustrated</title>
<title>Data on the Web</title>
<title>The Economics of Technology and Content for Digital TV</title>
</expensiveBooks>
通过更改为“ for”循环,我认为可以获得正确的结果。我将如何以及为什么留给对xquery更为了解的人,但也许注意到这种区别将对您自己或其他人有所帮助。
我的观点是,没有“ for”循环,就永远不会调用“ where”。
输出:
<expensiveBooks>
<title>TCP/IP Illustrated</title>
</expensiveBooks>
<expensiveBooks>
<title>The Economics of Technology and Content for Digital TV</title>
</expensiveBooks>
可能您正在考虑使用“ for”?
查询:
xquery version "3.1";
for $books in db:open("bib")//book
where $books/price > 60
return <expensiveBooks>
{ $books/title }
</expensiveBooks>
我将您的xml添加到“围兜”数据库中以供参考,否则与直接引用文档相同。
有趣。