2014-10-07 31 views
0

我正在努力解決XQuery問題。我有一個XML產品列表,其中包含來自2個不同產品目錄系統的產品(由於合併和收購)。一些產品是重複的(每個系統中有1個)。重複的產品名稱相同,但價格不同。我需要在列表中獲得不同的已排序產品,只顯示價格最低的產品

我想返回顯示最便宜的產品價格的不同產品的列表。例如,考慮這個輸入XML

<?xml version="1.0" encoding="UTF-8"?> 
<ns1:ProductList xmlns:ns1="http://www.mycorp.com/bus/prod/" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> 
    <ns1:Product> 
    <ns1:Id>2</ns1:Id> 
    <ns1:Name>Ace Ski Boot</ns1:Name> 
    <ns1:Description>An intermediate ski boot</ns1:Description> 
    <ns1:Price>109.99</ns1:Price> 
    <ns1:Warehouse>CZE_PRAGUE</ns1:Warehouse> 
    <ns1:Icon_url/> 
    <ns1:Latitude>50.07554</ns1:Latitude> 
    <ns1:Longitude>14.4378</ns1:Longitude> 
    </ns1:Product> 
    <ns1:Product> 
    <ns1:Id>SUM10012</ns1:Id> 
    <ns1:Name>Ace Ski Boot</ns1:Name> 
    <ns1:Description>Intermediate ski boot</ns1:Description> 
    <ns1:Price>200.0</ns1:Price> 
    <ns1:Warehouse>Seattle</ns1:Warehouse> 
    <ns1:Icon_url/> 
    <ns1:Latitude>47.60621</ns1:Latitude> 
    <ns1:Longitude>-122.33207</ns1:Longitude> 
    </ns1:Product> 
    <ns1:Product> 
    <ns1:Id>4</ns1:Id> 
    <ns1:Name>Ace Ski Pole</ns1:Name> 
    <ns1:Description>A ski pole for skiers with an intermediate skill level</ns1:Description> 
    <ns1:Price>29.99</ns1:Price> 
    <ns1:Warehouse>FRA_PARIS</ns1:Warehouse> 
    <ns1:Icon_url/> 
    <ns1:Latitude>48.856613</ns1:Latitude> 
    <ns1:Longitude>2.352222</ns1:Longitude> 
    </ns1:Product> 
    <ns1:Product> 
    <ns1:Id>SUM10022</ns1:Id> 
    <ns1:Name>Ace Ski Pole</ns1:Name> 
    <ns1:Description>Intermediate ski pole</ns1:Description> 
    <ns1:Price>21.950000762939453</ns1:Price> 
    <ns1:Warehouse>Seattle</ns1:Warehouse> 
    <ns1:Icon_url/> 
    <ns1:Latitude>47.60621</ns1:Latitude> 
    <ns1:Longitude>-122.33207</ns1:Longitude> 
    </ns1:Product> 

它顯示了2個重複的產品。我期待返回下面的XML:

<?xml version="1.0" encoding="UTF-8"?> 
<ns1:ProductList xmlns:ns1="http://www.mycorp.com/bus/prod/" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> 
    <ns1:Product> 
    <ns1:Id>2</ns1:Id> 
    <ns1:Name>Ace Ski Boot</ns1:Name> 
    <ns1:Description>An intermediate ski boot</ns1:Description> 
    <ns1:Price>109.99</ns1:Price> 
    <ns1:Warehouse>CZE_PRAGUE</ns1:Warehouse> 
    <ns1:Icon_url/> 
    <ns1:Latitude>50.07554</ns1:Latitude> 
    <ns1:Longitude>14.4378</ns1:Longitude> 
    </ns1:Product> 
    <ns1:Product> 
    <ns1:Id>SUM10022</ns1:Id> 
    <ns1:Name>Ace Ski Pole</ns1:Name> 
    <ns1:Description>Intermediate ski pole</ns1:Description> 
    <ns1:Price>21.950000762939453</ns1:Price> 
    <ns1:Warehouse>Seattle</ns1:Warehouse> 
    <ns1:Icon_url/> 
    <ns1:Latitude>47.60621</ns1:Latitude> 
    <ns1:Longitude>-122.33207</ns1:Longitude> 
    </ns1:Product> 

我見過的XQuery返回不同的值,而不是你需要選擇一個孩子(NS1:價格)的最低值元素。任何人都可以將我指向正確的方向嗎?提前謝謝了!

回答

3

如果您有可用的XQuery 3.0,那麼您可以使用group by表達式。例如:

xquery version "3.0"; 

declare namespace ns1 = "http://www.mycorp.com/bus/prod/"; 

for $product in //ns1:Product 
let $product-name := $product/ns1:Name 
group by $product-name 
return 
    <ns1:Product> 
    { 
     $product[xs:decimal(ns1:Price) eq min($product/xs:decimal(ns1:Price))] 
    } 
    </ns1:Product> 

如果你沒有的XQuery 3.0,但1.0的XQuery,那麼你就需要使用fn:distinct-values首先確定你想組的唯一產品名稱,從那裏你可以遍歷獨特的名稱和創建組(具有相同名稱的產品),然後您可以使用謂詞過濾以確定最便宜的產品。例如:

xquery version "1.0"; 

declare namespace ns1 = "http://www.mycorp.com/bus/prod/"; 

let $unique-product-names := distinct-values(//ns1:Product/ns1:Name) 
return 
    for $product-name in $unique-product-names 
    let $grouped-products := //ns1:Product[ns1:Name eq $product-name] 
    let $group-cheapest-price := min($grouped-products/xs:decimal(ns1:Price)) 
    return 
     $grouped-products[xs:decimal(ns1:Price) eq $group-cheapest-price] 
+0

不幸的是,我目前只能訪問XQuery 1.0。 – 2014-10-08 16:43:47

+0

我剛剛爲您更新了一個XQuery 1.0示例 – adamretter 2014-10-08 21:24:18

+0

傑出!那就是訣竅。非常感謝你提供了一個美麗的解決方案。 – 2014-10-09 17:52:00

相關問題