摘要: Marklogic支持多种语言,XQuery作为一种流行方式,在Marklogic的官网http://www.marklogic.com中多有推荐,本节从XQuery的FLWOR 语法入题,通过一个个实例演示XQuery的使用场景。
数据准备
- 产品目录文件 catalog.xml
<catalog>
<product dept="鄂尔多斯">
<number>100873</number>
<name language="cn">连衣裙</name>
<colorChoices>米色</colorChoices>
</product>
<product dept="南极人">
<number>6380</number>
<name language="cn">毛呢外套</name>
</product>
<product dept="美够">
<number>4954</number>
<name language="cn">半身裙</name>
</product>
<product dept="美够">
<number>2561</number>
<name language="cn">百褶裙</name>
</product>
<product dept="果国际">
<number>1697</number>
<name language="cn">牛仔裤</name>
<colorChoices>蓝色</colorChoices>
<desc>我最喜欢<i>A字裙</i></desc>
</product>
</catalog>
- 产品价格文件 prices.xml
<prices>
<priceList effDate="2016-10-13">
<prod num="100873">
<price currency="RMB">299</price>
<discount type="CLR">10.00</discount>
</prod>
<prod num="6380">
<price currency="RMB">699</price>
</prod>
<prod num="4954">
<price currency="RMB">99</price>
<discount type="CLR">3.99</discount>
</prod>
</priceList>
</prices>
- 商品订单文件 order.xml
<order num="1010598248" date="2016-09-15">
<item dept="鄂尔多斯" num="100873" quantity="1" color="米色"/>
<item dept="美够" num="4954" quantity="1"/>
<item dept="美够" num="2561" quantity="2"/>
<item dept="果国际" num="1697" quantity="1" color="白色"/>
<item dept="果国际" num="1697" quantity="1" color="蓝色"/>
<item dept="南极人" num="6380" quantity="1" color="黑色"/>
</order>
语法举例
- 完整的FLWOR语法
for $prod in fn:doc("catalog.xml")/catalog/product
let $name := $prod/name
where $prod/@dept = "美够"
order by $prod/number
return $name
得到的结果是两个数组形式的Element
<name language="cn">百褶裙</name>
<name language="cn">半身裙</name>
- 简化FLWOR语句
for $prod in doc("catalog.xml")/catalog/product
where $prod/@dept = "美够"
order by $prod/number
return $prod/name
在Marklogic语法中,命名空间fn
可以省略;使用let
可以使代码更清新,但有时可以偷懒简化
- 继续简化
for $x in doc("catalog.xml")//product[@dept = "美够"]
order by $x/number
return $x/name
有时候,能省则省,本来就是很简单的事情,干嘛搞的那么复杂呢?
- 可以把结果包装一下,使其变成一个node
<tr>{
for $x in doc("catalog.xml")//product[@dept = "美够"]
order by $x/number
return $x/name
}</tr>
这样,就在整个结果集外面多了一层标签
<tr>
<name language="cn">百褶裙</name>
<name language="cn">半身裙</name>
</tr>
- 也可以对每一个单独的结果包装
<tr>{
for $x in doc("catalog.xml")//product[@dept = "美够"]
order by $x/number
return <td>{$x/name}</td>
}</tr>
这个结果形式像不像HTML中的table样式
<tr>
<td><name language="cn">百褶裙</name></td>
<td><name language="cn">半身裙</name></td>
</tr>
- 如果只取Element中的数据
<tr>{
for $x in doc("catalog.xml")//product[@dept = "美够"]
order by $x/number
return <td>{data($x/name)}</td>
}</tr>
可以使用fn:data
函数,或者fn:string
函数,或者类似这样的表达式<td>{$x/name/text()}</td>
<tr>
<td>百褶裙</td>
<td>半身裙</td>
</tr>
- 有时候,可能需要将多个XML组合成一个新的形式
for $item in doc("order.xml")//item
let $name := doc("catalog.xml")//product[number = $item/@num]/name
return <item num="{$item/@num}"
name="{$name}"/>
将catalog数据与order数据结合,产生新的报表
<items>
<item num="100873" name="连衣裙"></item>
<item num="4954" name="半身裙"></item>
<item num="2561" name="百褶裙"></item>
<item num="1697" name="牛仔裤"></item>
<item num="1697" name="牛仔裤"></item>
<item num="6380" name="毛呢外套"></item>
</items>