2016-04-05 62 views
3

還是有點難度的標題說明問題,所以這裏是一個特定的XML文件的例子和代碼應返回的內容:的Xquery - 計算特定元素的具有特定屬性的數量

<objects> 
    <object type='Brick' to='Up' /> 
    <object type='Cross' to='Down' /> 
    <object type='Brick' to='Left' /> 
    <object type='Brick' to='Up' /> 
    <object type='Circle' to='Right' /> 
    <object type='Circle' to='Right' /> 
</objects> 

所以我有3個對象類型:Brich,Circle和Cross,以及3個,上,下,左和右。我想使用XQuery得到的東西,如:

<objects> 
    <object type="Brick"> 
     <where to="Up" count="2" /> 
     <where to="Down" count="0" /> 
     <where to="Left" count="1" /> 
     <where to="Right" count="2" /> 
    </object> 
    <object type="Cross"> 
    . 
    . 
    . 
</objects> 

基本上,每種類型的,我想要得到正確的子元素,下,左,和了它們出現該對象類型的次數。我知道,由於存在限制,我可以對每一個計數進行硬編碼,並且有一串let語句,但是我希望有人能夠提出一個更好的方法來做到這一點。

+0

您可以使用XQuery 3對您的元素進行分組嗎? –

+0

我試圖在Xquery 1.0中做到這一點 –

回答

2

這裏是一個完全動態的版本(沒有硬編碼),distinct-values(...)是您在XQuery 1.0中的朋友:

<objects>{ 
    let $directions := distinct-values(//@to) 
    for $type in distinct-values(//object/@type) 
    return <object type="{$type}">{ 
    for $to in $directions 
    return <where to="{$to}" count="{count(//object[@type = $type and @to = $to])}"/> 
    }</object> 
}</objects> 
0

如果對象類型和方向相當靜態並且您有很多對象,那麼您可能最好列出已知值,而不是使用distinct-values,這對於大型序列可能會很慢。

let $object-types := ('Brick', 'Circle', 'Cross') 
let $directions := ('Up', 'Down', 'Left', 'Right') 
for $t in $object-types 
return element object { 
    attribute type { $t }, 
    for $d in $directions 
    let $count := count($objects/object[@type = $t][@to = $d]) 
    return element where { 
    attribute to { $d }, 
    attribute count { $count } 
    } 
} 

但是,如果你無法知道的輸入值的時間提前,你可以建立這些值動態,如:

let $object-types := distinct-values($objects/object/@type) 
... 
相關問題