#xpath #xquery #basex
#xpath #xquery #basex
Вопрос:
Я пишу функцию Xquery для BaseX, которая получает один из аргументов в качестве имени узла элемента. Затем это имя используется в Xpath, но в целом я не могу преобразовать строку в элемент.
Вот как выглядит метод
declare function prefix:getElementWithValue($root as document-node()?, $elem as xs:string?, $minVal as xs:float?, $maxVal as xs:float?)
as element()*
{
let $e := element {$elem} {""}
for $x in $root//SUBELEM
return if ($x//$e/@ATTRIB>=$minVal and $x//$e/@ATTRIB<=$maxVal) then ($x)
};
и вызов
return prefix:getElementWithValue($db, "SomeElem", 10.0, 10.0)
и я получаю пустой ответ от этого. Если я заменю на $x//$e
, $x//SomeElem
он вернет правильный ответ. Из QueryPlan я вижу, что $e
обрабатывается как буквальное значение. XPATH не $x//SomeElem/@ATTRIB
является, но $x//$e/@ATTRIB
Итак, мой вопрос в том, как скрыть строку для типа, который можно использовать в XPATH?
Ответ №1:
В XQuery нет стандартной функции для вычисления динамически построенного выражения XPath.
Однако многие процессоры XQuery предлагают какую-то функцию расширения, которая делает это. Например, BaseX предлагает запрос:eval():
https://docs.basex.org/wiki/XQuery_Module#xquery:eval
Обратите внимание, что переменные в XQuery представляют значения, а не фрагменты текста выражения. Ваше выражение $x//$e/@ATTRIB
эквивалентно $x//"SomeElem"/@ATTRIB
, что сильно отличается от $x//SomeElem/@ATTRIB
.
Если вы знаете, что $elem
это всегда будет имя элемента, тогда вы можете написать $x//*[name()=$e]/@ATTRIB
. Но будьте осторожны с пространствами имен.