2010-09-29 68 views
0

我有一个XML结构,需要使用XQuery进行查询。 就我所能找到的而言,这可能甚至不可能,但是因为我对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> 

所以我的查询基本上是这样的: 获取所有产品的详细信息那里是属于“按月付费”一个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> 

回答

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> 
+0

谢谢Shcheklein!我会试试这:) – BoomShaka 2010-10-02 13:49:57

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]]