Dharmendra Kumar Singh
Dharmendra Kumar Singh

Reputation: 195

How to convert string to XPATH in BaseX

How can i convert string into XPATH, below is the code

let $ti := "item/title"
let $tiValue :=  "Welcome to America"
return db:open('test')/*[ $tiValue = $ti]/base-uri()

Upvotes: 0

Views: 147

Answers (2)

Michael Kay
Michael Kay

Reputation: 163625

Your question is very unclear - the basic problem is that you've shown us some code that doesn't do what you want, and you're asking us to work out what you want by guessing what was going on in your head when you wrote the incorrect code.

I suspect -- I may be wrong -- that you were hoping this might somehow give you the result of

db:open('test')/*[item/title = $ti]/base-uri()

and presumably $ti might hold different path expressions on different occasions.

XQuery 3.0/3.1 doesn't have any standard way to evaluate an XPath expression supplied dynamically as a string (unless you count the rather devious approach of using fn:transform() to invoke an XSLT transformation that uses the xsl:evaluate instruction).

BaseX however has an query:eval() function that will do the job for you. See https://docs.basex.org/wiki/XQuery_Module

Upvotes: 1

Christian Grün
Christian Grün

Reputation: 6229

Here is one way to solve it:

let $ti := "item/title"
let $tiValue :=  "Welcome to America"

let $input := db:open('test')
let $steps := tokenize($ti, '/')
let $process-step := function($input, $step) { $input/*[name() = $step] }
let $output := fold-left($input, $steps, $process-step)
let $test := $output[. = $tiValue]
return $test/base-uri()

The path string is split into single steps (item, title). With fold-left, all child nodes of the current input (initially db:open('test')) will be matched against the current step (initially, item). The result will be used as new input and matched against the next step (title), and so on. Finally, only those nodes with $tiValue as text value will be returned.

Upvotes: 1

Related Questions