tags:

views:

29

answers:

2

I have the below xml, in which I need to do the following:

If the value of both title and text element are same, sort those list element based on score attribute

For e.g.: Here the value of title and text for 1st and 3rd list element are same, so these two should be sort based on score and display the list which has the highest score and discard others.

How can I achieve this?

Desired output:

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

Assuming I understand you correctly, that you want to only return list nodes where the title and text are the same and the nodes of those for each value that have the highest score. And since you tagged the question "xquery" I assume you want to do it in 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)
mbrevoort
A: 

If you are wanting to order the list's by score instead of just returning the high score (like mbrevoort's answer) you could do the following:

Note: I added an extra list to the XML to show a list that had a title and text that didn't match.

Input XML (input.xml in the 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>

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

(This was run using Saxon-HE XQuery 9.)

DevNull