2016-04-05 6 views
3

Ein wenig schwierig, das Problem in einem Titel zu erklären, so ist hier ein bestimmtes XML-Datei Beispiel und etwas der Code zurückgeben sollte:Xquery - zählen die Anzahl bestimmter Elemente mit bestimmten Attributen

<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> 

Also ich habe 3 Objekttypen: Brich, Circle und Cross sowie 3 To's, Up, Down, Left und Right. Ich mag xquery nutzen, um etwas wie zu bekommen:

<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> 

grundsätzlich für jeden Typen, ich will Unterelemente für Recht erhalten, unten, links und oben mit der Anzahl, wie oft sie für diesen Objekttyp angezeigt. Ich weiß, dass, da es Einschränkungen gibt, ich nur jede einzelne Zählung fest codieren kann und eine Reihe von Aussagen habe, aber ich hoffe, dass jemand einen besseren Weg vorschlagen könnte.

+0

Können Sie mit XQuery 3 Ihre Elemente gruppieren? –

+0

Ich versuche dies in Xquery 1.0 zu tun –

Antwort

2

Hier ist eine vollständig dynamische Version (ohne Hartcodierung), distinct-values(...) ist Ihr Freund in 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

Wenn die Objekttypen und Richtungen ziemlich statisch sind und Sie viele Objekte haben, dann ist es wahrscheinlich besser, die bekannten Werte aufzulisten, anstatt distinct-values zu verwenden, was bei großen Sequenzen langsam sein kann.

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 } 
    } 
} 

Aber wenn Sie nicht die Eingangswerte im Voraus wissen, könnten Sie diese Werte dynamisch wie bauen könnten:

let $object-types := distinct-values($objects/object/@type) 
... 
Verwandte Themen