запрос параметра xquery

Я пытаюсь запросить существующий db с помощью xquery, беря параметры из URL-адреса и создавая параметры поиска

xquery version "1.0";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare option exist:serialize "method=xml media-type=text/xml omit-xml-declaration=no indent=yes";

let $param1:= request:get-parameter("param1",'0')

let $person :=
    if($param1 = '0') 
    then "'*'"
    else concat('contributions/person/@val="',$param1,'"')

return

<xml>
{
    for $x in subsequence(//foo/bar[$person],1,3)
    return $x
}
</xml>

Приведенный выше код показывает, что я получаю параметр из url $ param1.

переменная $ person проверяет наличие параметра и на основе этого создает параметр запроса. Эта переменная работает нормально, при тестировании она выводит либо '*' без параметра, либо

contributions/person/@val='hello, world'

Когда я запускаю запрос, он распечатывается, как если бы значение было «*». Могу ли я передать такую ​​переменную в части for $ x? Я пробовал поставить concat ($ person, '') с теми же результатами. Жесткое кодирование полного пути дает мне результаты, которые я ищу, но я хочу создать что-то более динамичное.

Примечание: есть только одна переменная, $ person, но будут и другие, как только я заставлю ее работать.


person user9418    schedule 22.10.2012    source источник
comment
Я думаю, проблема в том, что $ person теперь строка, а теперь путь. Но мне кажется, я не могу не хранить это как струну.   -  person user9418    schedule 22.10.2012


Ответы (1)


Я думаю, что в идеале вам следует избегать динамической оценки строк. В этом примере довольно простая реорганизация решила бы проблему без этого:

<xml>
{
  for $x in subsequence(//foo/bar[
    if ($param1 = '0')
    then *
    else (contributions/person/@val = $param1)
  ],1,3)
  return $x
}
</xml>

Однако вы можете использовать eval(), но помните, что существуют риски для безопасности:

<xml>
{
  for $x in subsequence(eval(
    concat('//foo/bar[',$person,']')
  ),1,3)
  return $x
}
</xml>
person wst    schedule 22.10.2012
comment
Это было то, что я искал =) Спасибо! - person user9418; 22.10.2012
comment
Возможно, заговорил слишком рано. Если бы я хотел проверить $ param2 с тем же выражением, но вклад / ссылка / @ val = 'test'. Как бы я это сделал? Я сделал 'and if ($ param2 = 0)', но получаю следующее сообщение об ошибке: - ошибка FORG0006: effectiveBooleanValue: первый элемент '(false, false)' не является узлом, а длина последовательности ›1 - person user9418; 22.10.2012
comment
@ user9418 Если я вас правильно понял, думаю, вам просто нужно if (($param1 = '0') and ($param2 = '0')) - person wst; 22.10.2012
comment
Я пытаюсь достичь более многогранного поиска, такого как pastebin.com/CYAdpUi5, но на основе вашего пример Я получаю сообщение об ошибке в кислороде в первую очередь. Когда я запускаю запрос, я получаю «Ошибка синтаксического анализа: имя элемента, содержащее пробел: неожиданный токен: затем в строке: 15 столбец: 25» - person user9418; 23.10.2012
comment
Хорошо, удалось заставить его работать pastebin.com/8jTcWjuy - производительность немного медленная. Но спасибо за вашу помощь - person user9418; 23.10.2012
comment
Вероятно, не самый эффективный код (имеется в виду ваша ссылка pastebin, которую вы только что сказали, работает). Например, цикл for не нужен - просто вызовите функцию подпоследовательности напрямую, а не перебирайте ее результаты, чтобы вернуть их все. Кроме того, вы проверяете, дважды ли ($ param1 = '0'); Бьюсь об заклад, вы имели в виду вторую для тестирования $ param2, не так ли? Наконец, вы можете проверить статью Как оптимизировать ваши запросы на сайте eXist-db exist-db.org /exist/tuning.xml - применимы разделы 4.3 и 4.6. - person Joe Wicentowski; 24.10.2012