2010-07-20 7 views
0

je le xml ci-dessous, où je dois faire ce qui suit:XML Comparaison et tri requête

Si la valeur des deux éléments de titre et le texte sont les mêmes, sorte les éléments de la liste en fonction de l'attribut score

Par exemple: Ici, la valeur du titre et du texte pour les éléments de liste 1 et 3 est la même, donc ces deux devraient être triés en fonction du score et afficher la liste qui a le score le plus élevé.

Comment puis-je y parvenir?

sortie souhaitée:

<list> 
    <title>abcd</title> 
    <text>abcd</text> 
    <score>2</score> 
</list> 

XML ----- -----

<result> 
<list> 
    <title>abcd</title> 
    <text>abcd</text> 
    <score>1</score> 
</list> 
<list> 
    <title>efgh</title> 
    <text>efgh</text> 
    <score>3</score> 
</list> 
<list> 
    <title>abcd</title> 
    <text>abcd</text> 
    <score>2</score> 
</list> 
<result> 

Répondre

0

En supposant que je vous comprends bien, que vous voulez retourner uniquement les noeuds de la liste où le titre et le texte est le même et les nœuds de ceux pour chaque valeur qui ont le score le plus élevé. Et puisque vous avez étiqueté la question "xquery" je suppose que vous voulez le faire dans xquery.

declare function local:getHighScores($result as node()) as node()* { 

    let $same := 
    for $i in $result/list 
    where ($i/title/text() = $i/text/text()) 
    return $i 

    let $unique_titles := fn:distinct-values($same/title/text()) 

    return 
    for $title in $unique_titles 
    return 
     (
     for $j in $result/list 
     where $j/title = $title 
     order by $j/score descending 
     return $j 
    )[1] 

}; 

let $xml := <result> 
<list> 
    <title>abcd</title> 
    <text>abcd</text> 
    <score>1</score> 
</list> 
<list> 
    <title>efgh</title> 
    <text>efgh</text> 
    <score>3</score> 
</list> 
<list> 
    <title>abcd</title> 
    <text>abcd</text> 
    <score>2</score> 
</list> 
<list> 
    <title>abcdg</title> 
    <text>abcde</text> 
    <score>2</score> 
</list> 
</result> 


return local:getHighScores($xml) 
0

Si vous êtes désireux de commander les list « s selon le score au lieu de simplement retourner le score élevé (comme la réponse de mbrevoort), vous pouvez effectuer les opérations suivantes:

Note: J'ai ajouté une list supplémentaire à la XML pour montrer une liste qui avait un title et text qui ne correspondait pas.

XML d'entrée (input.xml dans le XQuery):

<?xml version="1.0" encoding="UTF-8"?> 
<result> 
    <list> 
     <title>abcd</title> 
     <text>abcd</text> 
     <score>1</score> 
    </list> 
    <list> 
     <title>abcd</title> 
     <text>efgh</text> 
     <score>6</score> 
    </list> 
    <list> 
     <title>efgh</title> 
     <text>efgh</text> 
     <score>3</score> 
    </list> 
    <list> 
     <title>abcd</title> 
     <text>abcd</text> 
     <score>2</score> 
    </list> 
</result> 

XQuery:

<result> 
{ 
for $list in doc("file:///C:/xquery_test/input.xml")/result/list[title = text] 
order by $list/title, $list/score 
return 
    $list 
}  
</result> 

résultant XML:

<?xml version="1.0" encoding="UTF-8"?> 
<result> 
    <list> 
     <title>abcd</title> 
     <text>abcd</text> 
     <score>1</score> 
    </list> 
    <list> 
     <title>abcd</title> 
     <text>abcd</text> 
     <score>2</score> 
    </list> 
    <list> 
     <title>efgh</title> 
     <text>efgh</text> 
     <score>3</score> 
    </list> 
</result> 

(Ceci a été exécuté en utilisant Saxon-HE XQuery 9.)