问题描述
我正在为BaseX编写Xquery函数,该函数获取参数之一作为元素节点的名称。然后在Xpath中使用该名称,但是通常我无法将字符串转换为element。
这是该方法的外观
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中使用的字符串?
解决方法
XQuery没有用于评估动态构造的XPath表达式的标准函数。
但是,许多XQuery处理器提供了某种扩展功能来执行此操作。例如,BaseX提供了query: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
。但是要注意名称空间。