views:

127

answers:

2

Hi all, I use Apache Tomcat's Exist DB as an XML database and am trying to construct a sequence by passing the following xpath, defined in FLWOR's 'let' clause:

$xpath := $root/second/third

into a locally defined function declaration, like so:

declare function local:someFunction($uuid as xs:string?, $xpath as xs:anyAtomicType?)
{
  let $varOne := $xpath/fourth[@uuid = $uuid]/fifthRight
  let $varTwo := $xpath/fourth[@uuid = $uuid]/fifthLeft
  let $combined := ($varOne,$varTwo)
  return $combined
};

Of course, when entering this in the exist xquery sandbox, I get Type: xs:anyAtomicType is not defined. What should I use in place of it, or should I do this a different way?

Thanks in advance for any suggestions.

+1  A: 

I could not reproduce the error (xs:anyAtomicType not defined). However, maybe the following can help?

If $xpath (initially a node) is passed as an atomic-type parameter (thus is atomized), it will definitely throw a type error XPTY0019 when you attempt to navigate in your function ($xpath/fourth). Does the following code work on your side (passed as node()* instead)?

declare function local:someFunction($uuid as xs:string?, $xpath as node()*)
{
  let $varOne := $xpath/fourth[@uuid = $uuid]/fifthRight
  let $varTwo := $xpath/fourth[@uuid = $uuid]/fifthLeft
  let $combined := ($varOne,$varTwo)
  return $combined
};

let $root :=
  <first>
    <second>
      <third>
        <fourth uuid="1">
          <fifthLeft>foo</fifthLeft>
          <fifthRight>bar</fifthRight>
        </fourth>
      </third>
    </second>
  </first>
let $xpath :=$root/second/third
return
local:someFunction("1", $xpath)

(Edit: forgot the star to allow any number of nodes)

xqib-team
Thank you xqib-team! using: $xpath as node()* solved my problem. I was looking at a hierarchy of atomic types that xQuery has built-in, but of course since I am passing a node, it isn't categorized as such. I really don't understand the data type definitions in xQuery all that well, and haven't found a good set of tutorials that illustrate how to play around with all of them.Thanks again.
topmulch
A: 

An expression like $root/second/third in general yields a sequence of items so it's not helpful to think of it as a path. Using the type xs:anyAtomicType? will coerce the items to a atom.

You can simplify the function to

declare function local:y($uuid as xs:string?, $xpath as item()*)
{
  $xpath/fourth[@uuid = $uuid]/(fifthRight,fifthLeft)
};

BTW eXist db is an independent open source project not connected to Apache or Tomcat although it uses Apache components like Xalan and Lucene

Chris Wallace
Hi Chris, I used item()* and that worked also. Although, I needed the function to return a sequence.I apologize for stating that Exist DB is part of the Apache Tomcat project - I knew that too. In fact, on another machine, I am running Jetty as the web server and not Apache.Thank you for your response.
topmulch