Как преобразовать строку в Xpath в функции Xquery (BaseX)

#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 . Но будьте осторожны с пространствами имен.