0

In order to learn XQuery I tried to run the following XQuery command in BaseX

let $x := doc("test.xq")//h2/following-sibling return  $x::h2

I supposed it should be equivalent to

let $x := doc("test.xq")//h2/following-sibling::h2 return  $x

But it gives the following error and doesn't work while the second command works

Error:
Stopped at D:/Program Files/BaseX/data/test.xq, 1/66:
[XPST0003] Unexpected end of query: '::h2'.

In general, how can I select some nodes (h2) in the context provided by a variable ($x := doc("test.xq")//h2/following-sibling)

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
Ahmad
  • 8,811
  • 11
  • 76
  • 141

2 Answers2

1

You can't separate the expression at that part, see following-sibling::h2 as one unit. You can do the following instead :

let $x := doc("test.xq")//h2 return  $x/following-sibling::h2
har07
  • 88,338
  • 12
  • 84
  • 137
  • Thank you, however as the other answer include, I need $x as a context to be used for further filters but I didn't know how then select h2 from them. – Ahmad Jun 09 '15 at 08:06
  • Not sure what you want exactly, the above `return` statement already used `$x` as context for selecting `following-sibling::h2` – har07 Jun 09 '15 at 08:09
  • yes but what if I want the context variable to be `$x/following-sibling`? `$x` in your case contains all `h2` elements but my aim is to have nodes after the first `h2` and the context should be specified in the variable – Ahmad Jun 09 '15 at 08:16
  • 1
    @Ahmad `doc("test.xq")//h2/following-sibling` _is_ a valid XPath expression but it doesn't mean what you want it to - it means find all the `h2` elements in that document and then take all of their child elements whose name is `following-sibling`. If (as is likely the case) there are no elements named `following-sibling` then the variable's value will be the empty sequence. The syntax error comes when you try using `::` immediately after a variable _reference_, which is not allowed by the XPath grammar. – Ian Roberts Jun 09 '15 at 10:34
1

That's not how variables work I'm afraid. It looks like you're trying to treat the variable declaration as a kind of "macro" and expecting its textual definition to be substituted in when the variable is referenced, but in fact XQuery variables are more like local variables in C or Java - the definition expression is evaluated to give a value or sequence and when you refer to the variable you get that value back.

So both the definition and referencing expressions need to be valid expressions in their own right. If you wanted to store the list of all following sibling elements in the variable and then later filter for just the h2 elements you'd need something like

let $x := doc("test.xq")//h2/following-sibling::* return  $x[self::h2]
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183