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)