2016-04-14 57 views
0

我很難根據需要應用的某些合併規則對一組XML進行排序。我在XQuery 1.0中這樣做,並且一直在玩獨特值函數,但卻很難將我需要的所有記錄聯繫起來。在XQUERY中排序和合並

我嘗試應用的邏輯是

  • 需要有存在的頻率和付款人和地方貢獻類型是一樣的每個組合中的一種發生。
  • 出現一次時是具有最近的日期是組合的實例
  • 如果細節出現在使用相同的,最近的日期,日期,付款人和頻率則需要對它們進行合併,使得同一記錄顯示該頻率和該特定日期的付款人的金額是該日期支付的總金額。
  • 如果列表中存在超過記錄,則需要合併詳細信息以得出具有最近日期的組合的實例。

任何幫助將非常感激。

 <transaction_history> 
     <contribution_transaction contribution_type="Type A" currency="GBP"> 
      <date>2015-12-31</date> 
      <payer>Employer</payer> 
      <amount>5042.38</amount> 
      <frequency>Quarterly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type A" currency="GBP"> 
      <date>2015-12-31</date> 
      <payer>Employer</payer> 
      <amount>4676.94</amount> 
      <frequency>Monthly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type B" currency="GBP"> 
      <date>2015-09-08</date> 
      <payer>Employer</payer> 
      <amount>4317.52</amount> 
      <frequency>Monthly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type A" currency="GBP"> 
      <date>2015-12-31</date> 
      <payer>Employer</payer> 
      <amount>9393.11</amount> 
      <frequency>Quarterly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type A" currency="GBP"> 
      <date>2015-10-02</date> 
      <payer>Employee</payer> 
      <amount>3944.49</amount> 
      <frequency>Monthly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type B" currency="GBP"> 
      <date>2015-12-31</date> 
      <payer>Employee</payer> 
      <amount>3675.85</amount> 
      <frequency>Monthly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type B" currency="GBP"> 
      <date>2015-10-02</date> 
      <payer>Employee</payer> 
      <amount>3385.69</amount> 
      <frequency>Monthly</frequency> 
     </contribution_transaction> 
     <contribution_transaction contribution_type="Type A" currency="GBP"> 
      <date>2015-12-31</date> 
      <payer>Employee</payer> 
      <amount>7369.64</amount> 
      <frequency>Monthly</frequency> 
     </contribution_transaction> 
    </transaction_history> 

<contribution_transaction contribution_type="Type A" currency="GBP"> 
     <date>2015-12-31</date> 
     <payer>Employer</payer> 
     <amount>5042.38</amount> 
     <frequency>Quarterly</frequency> 
    </contribution_transaction> 
<contribution_transaction contribution_type="Type A" currency="GBP"> 
     <date>2015-12-31</date> 
     <payer>Employer</payer> 
     <amount>5042.38</amount> 
     <frequency>Quarterly</frequency> 
    </contribution_transaction> 

的例子會導致:

<contribution_transaction contribution_type="Type A" currency="GBP"> 
     <date>2015-12-31</date> 
     <payer>Employer</payer> 
     <amount>10084.76</amount> 
     <frequency>Quarterly</frequency> 
    </contribution_transaction> 
+0

應該發生什麼如果有多個'contribution_transaction'具有相同的'frequency','payer'和'date'? –

+0

嗨,Leo,那麼金額將需要加總,然後導致只有一個contribution_transaction。實際上我需要考慮貢獻類型屬性,我已經意識到我忘了包含這些屬性。 – user1905307

回答

0

您可以在其他以後做兩個嵌套集團之一:

for $frequency in distinct-values(//frequency) 
let $contrib := //contribution_transaction[frequency = $frequency] 
for $payer in distinct-values($contrib/payer) 
let $res := $contrib[payer = $payer] 
let $min-date := min($res/date/xs:date(.)) 
return <result frequency="{$frequency}" payer="{$payer}">{ 
    (: do something clever with the relevant transactions here :) 
    $res[xs:date(date) = $min-date] 
}</result> 

由於您的日期格式與lexicog正確排序raphic排序順序,也可以只直接比較字符串:

for $frequency in distinct-values(//frequency) 
let $contrib := //contribution_transaction[frequency = $frequency] 
for $payer in distinct-values($contrib/payer) 
let $res := $contrib[payer = $payer] 
let $min-date := min($res/date/string()) 
return <result frequency="{$frequency}" payer="{$payer}">{ 
    (: do something clever with the relevant transactions here :) 
    $res[date = $min-date] 
}</result> 

由於您的處理器似乎只支持node() S作爲參數傳遞給fn:min(...),您可以使用此快速更換:

declare function local:min($seq) { 
    local:min((), $seq) 
}; 

declare function local:min($min, $seq) { 
    if(empty($seq)) then $min 
    else (
    let $first := $seq[1], $rest := $seq[position() > 1] 
    return (
     if($min < $first) then local:min($min, $rest) 
     else local:min($first, $rest) 
    ) 
) 
}; 

(: example usage :) 
local:min(('B', 'A', 'b')) 
+0

你認爲我需要在將日期傳遞給min()函數之前去掉日期中的連字符,不要認爲它會轉換爲double嗎? – user1905307

+0

在我的查詢中,我將它轉換爲'xs:date',這是XQuery原生支持的日期格式。比較兩個字符串總是按照字典順序進行;如果你想比較它們爲'xs:double's,你必須明確地轉換它們中的至少一個。 –

+0

感謝您的迴應。在嘗試此操作時,我似乎遇到錯誤:{err} XP0004 [{bea-err} XP0004b]:在表達式中發現類型不匹配。只有空序列滿足類型檢查規則。預期類型:節點*。 實際類型:{http://www.w3.org/2001/XMLSchema}date* – user1905307