2010-09-29 70 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]]