2
votes

I learned that every Xpath expression is also a valid Xquery expression. I'm using Oxygen 16.1 with this sample XML:

<actors>
    <actor filmcount="4" sex="m" id="15">Anderson, Jeff</actor>
    <actor filmcount="9" sex="m" id="38">Bishop, Kevin</actor>
</actors>

My expression is:

//actor/@id

When I evaluate this expression in Oxygen with Xpath 3.0, I get exactly what I expect:

15
38

However, when I evaluate this expression with Xquery 3.0 (also 1.0), I get the message: "Your query returned an empty sequence.

Can anyone provide any insight as to why this is, and how I can write the equivalent Xquery statement to get what the Xpath statement did above?

1
Are you sure you don't want //actors/actor/@id?wst
//actors/@id most certainly will not return 15 or 38 when run against the content you provided with a compliant XPath engine.Charles Duffy
Are you sure you haven't run //actor/@id or //actors//@id in the XPath engine? If you get any results on this document for //actor/@id, you should report an issue with the Oxygen developers.Jens Erat
@Jens Erat you want to write //actors/@idKachna
Yes, I wanted to, of course. Can't edit the comment any more. It seems thet my guess of a typo was right anyway, reading the comments to the answer.Jens Erat

1 Answers

5
votes

Other XQuery implementations do support this query

If you want to validate that your query (as corrected per discussion in comments) does in fact work with other XQuery implementations when entered exactly as given in the question, you can run it as follows (tested in BaseX):

declare context item := document { <actors>
    <actor filmcount="4" sex="m" id="15">Anderson, Jeff</actor>
    <actor filmcount="9" sex="m" id="38">Bishop, Kevin</actor>
</actors> };

//actor/@id

Oxygen XQuery needs some extra help

Oxygen XML doesn't support serializing attributes, and consequently discards them from a result sequence when that sequence would otherwise be provided to the user.

Thus, you can work around this with a query such as the following:

  • //actor/@id/string(.)
  • data(//actor/@id)

Below applies to a historical version of the question.

Frankly, I would not expect //actors/@id to return anything against that data with any valid XPath or XQuery engine, ever.

The reason is that there's only one place you're recursing -- one // -- and that's looking for actors. The single / between the actors and the @id means that they need to be directly connected, but that's not the case in the data you give here -- there's an actor element between them.

Thus, you need to fix your query. There are numerous queries you could write that would find the data you wanted in this document -- knowing which one is appropriate would require more information than you've provided:

  • //actor/@id - Find actor elements anywhere, and take their id attribute values.
  • //actors/actor/@id - Find actors elements anywhere; look for actor elements directly under them, and take the id attribute of such actor elements.
  • //actors//@id - Find all id attributes in subtrees of actors elements.
  • //@id - Find id attributes anywhere in the document.

...etc.