2014-11-24 83 views
0

我在我尝试的XQuery XQuery中XQuery来组XML元素

<Sheets> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>830</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5459</ROI> 
     <TPI>830</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5678</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>17473</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>857</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5713</ROI> 
     <TPI>857</TPI> 
    </Sheet> 
</Sheets> 

一些分组,我想通过一个动态值数说4 ...我希望我的XML组4种元素一组像

<Sheets> 
    <set> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>830</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5459</ROI> 
     <TPI>830</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5678</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    </set> 
    <set> 
    <Sheet> 
     <ROI>17473</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>857</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5713</ROI> 
     <TPI>857</TPI> 
    </Sheet> 
    </set> 
</Sheets> 

一样,组4片,以一组等4一组,最后剩下他们中的一个设置

回答

0

你可以使用subsequence()和递归调用的函数。

实施例...

XML输入

<Sheets> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>830</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5459</ROI> 
     <TPI>830</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5678</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>17473</ROI> 
     <TPI>856</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5350</ROI> 
     <TPI>857</TPI> 
    </Sheet> 
    <Sheet> 
     <ROI>5713</ROI> 
     <TPI>857</TPI> 
    </Sheet> 
</Sheets> 

的XQuery($groupSize4通过)

declare variable $groupSize external; 

declare function local:group($set as node()*, $size as xs:integer) as item()* { 
    <set>{subsequence($set,1,$size)}</set>, 
    if (count($set)>$groupSize) then 
     local:group(subsequence($set,$groupSize+1),$groupSize) 
    else 
     () 
}; 

<Sheets>{local:group(/*/*,$groupSize)}</Sheets> 

XML输出

<Sheets> 
    <set> 
     <Sheet> 
     <ROI>5350</ROI> 
     <TPI>830</TPI> 
     </Sheet> 
     <Sheet> 
     <ROI>5459</ROI> 
     <TPI>830</TPI> 
     </Sheet> 
     <Sheet> 
     <ROI>5350</ROI> 
     <TPI>856</TPI> 
     </Sheet> 
     <Sheet> 
     <ROI>5678</ROI> 
     <TPI>856</TPI> 
     </Sheet> 
    </set> 
    <set> 
     <Sheet> 
     <ROI>17473</ROI> 
     <TPI>856</TPI> 
     </Sheet> 
     <Sheet> 
     <ROI>5350</ROI> 
     <TPI>857</TPI> 
     </Sheet> 
     <Sheet> 
     <ROI>5713</ROI> 
     <TPI>857</TPI> 
     </Sheet> 
    </set> 
</Sheets> 
1

如果你的XQuery 3.0可用,你可以使用一个tumbling window实现这个很容易:

xquery version "3.0"; 

let $group-size := 4 (: set your group size here :) 
return 

    <Sheets> 
    { 
     for tumbling window $window in /Sheets/Sheet 
     start at $start when fn:true() 
     end at $end when $end - $start eq $group-size - 1 
     return 
      <set>{$window}</set> 
    } 
    </Sheets> 

否则,如果你只拥有的XQuery 1.0提供给你,然后你可以用做简单的FLWOR表达式和位置谓词:

xquery version "1.0"; 

let $group-size := 4 (: set your group size here :) 
return 

    <Sheets> 
    { 
     for $group in (1 to round(count(/Sheets/Sheet) div $group-size) cast as xs:integer) 
     let $start := (1 * ($group - 1) * $group-size) + 1 
     let $end := $group * $group-size 
     return 
      <set>{/Sheets/Sheet[position() ge $start][position() le $end]}</set> 
    } 
    </Sheets>