10

I've tried a few things:

for $name in ('Hanz', 'Heinz', 'Hans', 'Huns', 'Hund')
where $name contains text 'Hans' using fuzzy
return $name | $name
(: returns error: Stopped at line 3, column 20: [XPTY0004] 
Union expression: node() expected, xs:string found. :)


for $name in ('Hanz', 'Heinz', 'Hans', 'Huns', 'Hund')
where $name contains text 'Hans' using fuzzy
return $name and $name
(: returns true :)

for $name in ('Hanz', 'Heinz', 'Hans', 'Huns', 'Hund')
where $name contains text 'Hans' using fuzzy
return $name, $name
(: returns error: Stopped at line 3, column 19: [XPST0008] 
Undefined variable $name. :)

What I'm trying to do is just return the name variable twice. Of course, I'd like to do something more complicated. For example, given a doc (taken from w3):

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book category="COOKING">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="WEB">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="WEB">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

</bookstore>

I've tried to execute some queries I've seen in accepted answers across Stack Overflow, and I've yielded negative results. For example:

let $sep := ','
for $x in doc('test')/bookstore
  where fn:matches($x/book, 'XC')
  return fn:string-join( ($x/book/title/text(), $x/book/author/text(), 
  $x/book/price/text()), $sep)
(: Stopped at line 3, column 31: [XPTY0004] Single item expected, 
(element book { ... }, element book { ... }, ...) found. :)

--

I'd like to return the author, year, and title of any book with the category attribute equal to "web", a title element whose language attribute is English and whose value is exactly "Learining XML" and whose any child contain the text "Erik T"; or whose year is later than 2003, whose any descendant contain the text XML, and whose price is less than 20.00USD.

I think this shows the versatility of XQuery. Without being able to return, and in fact input, a list of targets, the software is essentially useless. I've found there is not a solid answer or tutorial that covers even a small portion of the above query; however, there are queries on how to do mathematical comparisons and order-by functions. These are useful in their own way, but getting started, they aren't nearly as important as being able to return multiple columns of a table based on the results found therein.

1
  • One comment: you seem to be assuming the availability of XQuery with the "full text" extension, which is an optional feature. But you aren't assuming anything, despite the title, about XQuery 3.0. Commented Sep 17, 2012 at 8:10

1 Answer 1

16

You've been really close in your third attempt, just the parentheses have been missing:

for $name in ('Hanz', 'Heinz', 'Hans', 'Huns', 'Hund')
where $name contains text 'Hans' using fuzzy
return ($name, $name)

You can return arbitrary variables in this sequence.

Caveat: XQuery does not know nested sequences, if you try so, they will just get concatenated. If you need nested sequences, you will have to construct an XML tree which you will return, eg.

return <names>
         <name>{$name}</name>
         <name>{$name}</name>
       </names>

This one does not contain any sequences, but it should show the pattern.

6
  • Thanks. +1. I really appreciate this first step to superior documentation, which is really needed. I'm not sure where you learned this? However, I have verified that it works. Check out the query near the bottom of my question. It's rather large and complex, but it shows all the things that I would like to find better documentation on--all the things that are most useful. or statements, and statements, in all different parts of the query, you know? Commented Sep 17, 2012 at 7:34
  • 1
    I learned XQuery in some university lecture. I haven't had any look into it yet, but XQuery by Priscilla Walmsley is told to be a fine introduction into XQuery. There is a lack in online XQuery ressources, some Wikibook on it and lots of small references, but I don't know any great introduction. Have a look at <xqueryfunctions.com> for learning some patterns (and prevent building these templates yourself).
    – Jens Erat
    Commented Sep 17, 2012 at 7:45
  • 2
    Your mistake was a very simple and common one of not understanding operator precedence. There are two ways of learning this: through experience, and through reading the spec. It's quite true that there's a shortage of good learning resources for XQuery; in good measure that's because people these days don't expect to pay any money for such resources. Commented Sep 17, 2012 at 8:14
  • @Ranon, Thank you, for the references. I'll pick up that book. It has cover art that peaks my interest, automatically. I feel like XQuery is kind of an essential language, but I worry that it won't interface with websites. Commented Sep 17, 2012 at 8:43
  • @MichaelKay I wouldn't mind paying for a good resource, but even when I go to the book store, I like to have a good look inside the book, first. There's nothing worse, for me, than getting a new book and being disappointed by the author's lack of proper grammar, the poor formatting of the book, over-complexity of code blocks without clear explanation, etc. Not only documentation, but a resource that points to good documentation can't be found; so, it really is difficult to get started in XQuery, and I get the feeling that most programmers just avoid it, altogether, despite its many uses. Commented Sep 17, 2012 at 8:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.