xquery: положить выражение where в переменную? строит where-предложение через переменную? - PullRequest
0 голосов
/ 14 июня 2019

Интересно, возможно ли создать запрос, как при использовании Saxon 9.9HE (адресуемый baseX):

let $where := '$x//element[text() = "content"]'
for $x in db:open("my_db")//something
where $where 
return $x//something_else

В моем приложении выражение where строится внешне (PHP) на основе некоторыхусловия, и я просто хочу передать это сценарию xquery, чтобы я мог использовать один базовый сценарий для всех запросов, каждый из которых отличается только передаваемым предложением where.Другие переменные могут быть легко переданы в сценарий, поскольку они не содержат выражений пути, а содержат только скаляры.

Возможно ли иметь выражение в переменной?

У меня было несколько попыток с xquery:eval() и xquery:parse() (обе функции baseX), но безуспешно.В основном это ошибки неизвестная переменная $ x , контекст не объявлен или ожидание возврата Если ошибки не происходит, я получаю ВСЕ элементы, поскольку кажется, что предложение whereоценивать как true, возвращая, таким образом, просто все

Мой текущий обходной путь - прочитать скрипт xquery, заменить $ where и затем выполнить его.Есть ли хороший способ сделать это в одиночку xquery?

Ответы [ 2 ]

2 голосов
/ 14 июня 2019

Вся вставка и оценка запроса связана с проблемой внедрения кода, поэтому будьте осторожны с этим, но в BaseX вам необходимо объявить вашу переменную в прологе вашего строкового выражения where, а затем связать его:

let $where := 'declare variable $x external; $x//element[text() = "content"]'
for $x in db:open("my_db")//something
where xquery:eval($where, map { "$x" : $x })
return $x//something_else

Кажется более безопасным просто написать функцию или модуль запроса и использовать его вместо конструирования кода в виде строк.

0 голосов
/ 14 июня 2019

В саксонском эквиваленте

let $where := '$p1//element[text() = "content"]'
for $p1 in $collection//something
where saxon:evaluate($where, $x)
return $p1//something_else

Переменная ДОЛЖНА иметь имя $ p1. saxon :valuate ожидает выражение XPath, а не выражение XQuery, поэтому не должно быть пролога (т. е. объявления переменных).

Как и другие саксонские расширения, saxon:evaluate() требует Saxon-PE или выше.

Существует довольно запутанный способ сделать это без функций расширения, при условии, что процессор имеет полезную реализацию функции XPath 3.1 fn:transform(). Вы помещаете динамическое выражение в таблицу стилей:

let $ss := "<xsl:transform....><xsl:function name='Q{zzz}predicate' as='xs:boolean'><xsl:param name="p"><xsl:sequence select='$p/" + $condition + "'/></xsl:transform>"

, а затем оценить состояние, которое вы используете

fn:transform(map{'stylesheet-string':$ss, 'initial-function':QName('zzz', 'predicate'), 'function-params':map{QName('','p'):$x}})?output
...