将结果分组的XQuery语句

时间:2010-09-29 12:31:01

标签: group-by xquery

我有一个XML结构,我需要使用XQuery进行查询。 据我所知,这可能甚至不可能,但由于我对XQuery这么新,我想我可能会问。

我需要查询下面的XML并返回类似的内容:

<product>
 <title>Acer Liquid</title>
 <image>ACER-LIQUID.jpg</image>
 <networks>
  <network>O2O</network>
  <network>VOD</network>
 </networks>
 <colours>
  <colour>Blue</colour>
  <colour>Black</colour>
 </colours>
</product>

所以我的查询基本上是这样的: 获取所有产品详细信息,其中有一个属于“Pay Monthly”的salespackage指向它(通过main_product),并附加指向它的每个销售包中的网络属性。但是按product.product_model字段对结果进行分组。

源XML:

<root>
 <package>
  <title>package1</title>
  <categories><category group="Other" name="Pay Monthly"/></categories>
  <properties>
    <value key="main_product">PRODUCT#14649766#PART#ACERLIQUIDBLACK</value>
    <value key="network_code">O2O</value>
  </properties>
 </package>
 <package>
  <title>package2</title>
  <categories><category group="Other" name="Pay Monthly"/></categories>
  <properties>
    <value key="main_product">PRODUCT#14649700#PART#ACERLIQUIDBLUE</value>
    <value key="network_code">VOD</value>
  </properties>
 </package>
 <product>
  <title>Acer Liquid</title>
  <properties>
   <value key="product_code">PRODUCT#14649700#PART#ACERLIQUIDBLUE</value>
   <value key="product_model">Acer Liquid|ACER_LIQUID</value>
   <value key="product_image_url">ACER-LIQUID.jpg</value>
   <value key="colour">Blue</value>
  </properties>
 </product>
 <product>
  <title>Acer Liquid</title>
  <properties>
   <value key="product_code">PRODUCT#14649766#PART#ACERLIQUIDBLACK</value>
   <value key="product_model">Acer Liquid|ACER_LIQUID</value>
   <value key="product_image_url">ACER-LIQUID.jpg</value>
   <value key="colour">Black</value>
  </properties>
 </product>
</root>

2 个答案:

答案 0 :(得分:1)

XQuery 1.0的相当复杂的查询:

declare ordering unordered;

declare function local:values($items as node()*,
                              $property as xs:string) as xs:string* {
    distinct-values($items/properties/value[@key eq $property])
};

declare function local:filter($items as node()*, 
                              $property as xs:string,
                              $values as xs:string*) as node()* {
    $items[properties/value[@key eq $property] = $values]
};


let $packages := doc('source')/root/package[categories/category[@name eq 'Pay Monthly']]
let $products := local:filter(doc('source')/root/product, 
                              'product_code',
                              local:values($packages, 'main_product'))

for $model           in local:values($products, 'product_model')
let $model_products  := local:filter($products, 'product_model', $model)
let $model_packages  := local:filter($packages,
                                     'main_product',
                                     local:values($model_products, 'product_code'))

return
<product>
    {$model_products[1]/title}
    <image>{local:values($model_products[1], 'product_image_url')}</image>
    <networks>{
        for $net in local:values($model_packages, 'network_code')
        return <network>{$net}</network>
    }</networks>
    <colours>{
        for $cl in local:values($model_products, 'colour')
        return <colour>{$cl}</colour>
    }</colours>
</product>

答案 1 :(得分:0)

这个XQuery:

for $title in (/root/product/title)[index-of(/root/product/title,.)[1]]
let $ProductsProp := /root/product[title=$title]/properties/value
return 
<product>
    {$title}
    <image>{string(($ProductsProp[@key='product_image_url'])[1])}</image>
    <networks>{
        for $network in /root/package/properties
                                  [value[@key='main_product']
                                   = $ProductsProp[@key='product_code']]
                                  /value[@key='network_code']/string()
        return
        <network>{$network}</network>
    }</networks>
    <colours>{
        for $colour in $ProductsProp[@key='colour']/string()
        return
        <colour>{$colour}</colour>
    }</colours>
</product>

输出:

<product>
    <title>Acer Liquid</title>
    <image>ACER-LIQUID.jpg</image>
    <networks>
        <network>O2O</network>
        <network>VOD</network>
    </networks>
    <colours>
        <colour>Blue</colour>
        <colour>Black</colour>
    </colours>
</product>

注意:XPath 2.0分组表达式$vSeq[index-of($vSeq,.)[1]]