0

I have a XML like this:

<countries>
        <country name="Austria" population="8023244" area="83850">
            <city>
                <name>Vienna</name>
                <population>1583000</population>
            </city>
        </country>
        <country name="Spain" population="39181112" area="504750">
            <city>
                <name>Madrid</name>
                <population>3041101</population>
            </city>
        </country>
       [...]
</countries>

I need a xQuery expression to get the name of the most populated city, but i dont know how to do. Some ideas?

TheRedosan
  • 79
  • 2
  • 12

3 Answers3

1

Well, select the city elements, select the maximum population and then the city with that population for instance:

let $cities := //city,
      $max-pob := max($cities/population)
return $cities[population = $max-pob]/name

Or sort and take the first:

(for $city in //city
order by $city/population descending
return $city)[1]/name

You could also use the sort function:

sort(//city, (), function($c) { xs:decimal($c/population) })[last()]/name
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
1

The traditional way in XQuery 1.0 is

let $p := max(//population) 
return //city[population = $p]/name

But this has the disadvantage of scanning the data twice.

You can avoid this using higher-order functions, for example the eg:highest() function shown as an example in the spec at D4.6.1 (https://www.w3.org/TR/xpath-functions-31/#highest-lowest) or a fold operation:

let $top := fold-left(//city, head(//city), 
    function($top, $this) {
      if (number($this/population) ge number($top/population)) 
      then $this else $top
    })
return $top/name

Saxon provides an extension function saxon:highest which is equivalent to the eg:highest example in the spec, so you can write

saxon:highest(//city, function($city){number($city/population)})/name
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
0

You can try this:

//city[population = max(/countries/country/city/population)]/name
localghost
  • 419
  • 2
  • 6