XQuery сравнивает переменные как числа

Я хочу выпустить XQuery, который выводит цену трех CD, за вычетом цены самого дешевого CD. Я создал пользовательскую функцию sumtwomax(), которая принимает три целочисленных параметра и выдает сумму двух самых больших чисел. Это работает, когда я снабжаю его номерами. Но у меня есть проблема при предоставлении его с переменными из выражения FLWOR. Может ли кто-нибудь помочь мне с этим?

Вот мой XML-код:

<items>
  <item>
    <code>c002</code>
    <price>10</price>
    <rating>5</rating>
  </item>
  <item>
    <code>c006</code>
    <price>15</price>
    <rating>3</rating>
  </item>
  <item>
    <code>c004</code>
    <price>12</price>
    <rating>3</rating>
  </item>
  <item>
    <code>c001</code>
    <price>7</price>
    <rating>5</rating>
  </item>
  <item>
    <code>c003</code>
    <price>10</price>
    <rating>4</rating>
  </item>
  <item>
    <code>c005</code>
    <price>8</price>
    <rating>4</rating>
  </item>
</items>

А вот и мой XQuery:

declare namespace myfn = "http://www.brookes.ac.uk/P00601/xquery/functions";
declare function myfn:sumtwomax( $first,  $sec, $third)  { sum(($first, $sec, $third)) - min (($first, $sec, $third))};

for $d in doc("shop.xml") //item
let $price1 := xs:integer($d/price/data()[$d/code="c002"]) 
let $price2 := xs:integer($d/price/data()[$d/code="c004"]) 
let $price3 := xs:integer($d/price/data()[$d/code="c006"])
return
myfn:sumtwomax($price1, $price2, $price3)

В результате получается "0 0 0" вместо желаемого значения "15". Может ли кто-нибудь помочь с этим?

1 ответ

Решение

Выражение FLWOR не имеет никакого смысла в этом контексте: оно оценивает только один item одновременно (и returnодин результат за item), но выражения, которые вы запускаете в этом цикле, возвращают полезные результаты только в том случае, если они могут выполнять поиск по всем элементам, чтобы иметь возможность заполнить все три переменные (в отличие от только переменной, связанной с единственным элементом, повторяемым циклом в это время).

Рассмотрим вместо этого итерации items элементы (из которых есть только один), если вы действительно хотите сделать это FLWOR:

declare function myfn:sumtwomax( $first,  $sec, $third)  { sum(($first, $sec, $third)) - min (($first, $sec, $third))};

for $d in //items
let $price1 := xs:integer($d/item[code="c002"]/price)
let $price2 := xs:integer($d/item[code="c004"]/price) 
let $price3 := xs:integer($d/item[code="c006"]/price)
return myfn:sumtwomax($price1, $price2, $price3)

... или, удаляя ненужное for полностью:

declare function myfn:sumtwomax( $first,  $sec, $third)  { sum(($first, $sec, $third)) - min (($first, $sec, $third))};

let $price1 := xs:integer(//item[code="c002"]/price)
let $price2 := xs:integer(//item[code="c004"]/price) 
let $price3 := xs:integer(//item[code="c006"]/price)
return myfn:sumtwomax($price1, $price2, $price3)
Другие вопросы по тегам