views:

92

answers:

2

Hi,

I am trying to use a if condition to assign a value to a variable in an xquery. I am not sure how to do this.

This is what I tried:

declare namespace libx='http://libx.org/xml/libx2';
declare namespace atom='http://www.w3.org/2005/Atom';
declare variable $entry_type as xs:string external;
let $libx_node :=
    if ($entry_type = 'package' or 'libapp') then
      {element {fn:concat("libx:", $entry_type)} {()} }
    else if ($entry_type = 'module') then
      '<libx:module>
        <libx:body>{$module_body}</libx:body>
      </libx:module>'

This code throws an [XPST0003] Incomplete 'if' expression error. Can someone help me fix this?

Also, can someone suggest some good tutorials to learn xqueries.

Thanks, Sony

A: 

That's because in XQuery's conditional expression specification else-expression is always required:

[45]  IfExpr  ::=  "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle

So you have to write second else clause (for example, it may return empty sequence):

declare namespace libx='http://libx.org/xml/libx2';
declare namespace atom='http://www.w3.org/2005/Atom';
declare variable $entry_type as xs:string external;

let $libx_node :=
        if ($entry_type = ('package','libapp')) then
          element {fn:concat("libx:", $entry_type)} {()}
        else if ($entry_type = 'module') then
          <libx:module>
            <libx:body>{$module_body}</libx:body>
          </libx:module>
        else ()
... (your code here) ...

Some obvious bugs are also fixed:

  • don't need {} around computed element constructor;
  • most likely, you want if($entry_type = ('package', 'libapp'))

Concerning XQuery tutorials. The W3CSchools's XQuery Tutorial is a pretty good starting point.

Shcheklein
A: 

Thanks !

But, the code I showed was a simpler version of my query. What you suggested does not fit into the full query. Please see:

declare namespace libx='http://libx.org/xml/libx2';
declare namespace atom='http://www.w3.org/2005/Atom';
declare variable $doc_name as xs:string external;
declare variable $entry_type as xs:string external;
declare variable $feed       as xs:anyAtomicType := doc($doc_name)/atom:feed;
declare variable $metadata   as xs:anyAtomicType := doc('libx2_meta')/metadata;
let $curid := $metadata/curid
return replace value of node $curid with data($curid) + 1,

let $newid := data($metadata/curid) + 1
let $title := $entry_type
let $author_name := 'LibX Team'
let $author_uri := 'http://libx.org'
let $author_email := '[email protected]'
let $module_body := 'module body'
let $libx_node := 
  if($entry_type = 'package' or 'libapp') then
    element {fn:concat("libx:", $entry_type)} {()}
  else if($entry_type = 'module') then
    '<libx:module>
       <libx:body>{$module_body}</libx:body>
     </libx:module>'
  else ()
  return $libx_node  
return insert node
  <entry xmlns:libx="http://libx.org/xml/libx2" xmlns="http://www.w3.org/2005/Atom"&gt;
    <id>{$newid}</id>
    <title>New {$title}</title>
    <updated>{fn:current-dateTime()}</updated>
    <author>
      <name>{$author_name}</name>
      <uri>{$author_uri}</uri>
      <email>{$author_email}</email>
    </author>
    <content type="html">Content created by LibX Libapp Builder</content> 
    {$libx_node}
  </entry>
into $feed

Two return statements are not allowed in xquery ? I get the error:

java.io.IOException: Stopped at line 25, column 1: [XPST0003] Unexpected end of query: 'return insert n...'.

Thanks a lot !

  • sony
sony
[XPST0003] Unexpected end of query: 'return insert n...'.
sony
@sony: it's much better to edit initial question than writing answer with new version of the question
Shcheklein
@sony: just try to remove `return $libx_node`. I added it because didn't know your full query.
Shcheklein
@scheklein: Thanks! I will keep this in mind next time. But, after I run the query as you suggested, the child node libx:body doesn;t get inserted. I see this in my database: <entry xmlns="http://www.w3.org/2005/Atom" xmlns:libx="http://libx.org/xml/libx2"> <id>51</id> <title>New module</title> <updated>2010-09-10T15:14:25.173-04:00</updated> <author> <name>LibX Team</name> <uri>http://libx.org</uri> <email>[email protected]</email> </author> <content type="html">Content created by LibX Libapp Builder</content> <libx:module/> </entry>
sony
Please note that <libx:module/> is inserted rather than <libx:module> <libx:body> module body </libx:body> </libx:module>. The value of 'entry_type' here is 'module'
sony
@sony: because now you assign a string to the $libx_node var: `... then '<libx:module><libx:body>{$module_body}</libx:body></libx:module>' ...`. Seems you just need to remove single quotes: `... then <libx:module><libx:body>{$module_body}</libx:body></libx:module> ...`
Shcheklein
@Shcheklein: Yes, I removed the single quotes. It still doesn't work. Only <libx:module /> node gets inserted into the database for some reason.
sony
@sony: I believe, this a different question. Anyway, try firstly simple insert operations on your database. BTW, which one do you use? Try also to return $libx_node to see its value.
Shcheklein
@Shcheklein: Thanks a lot for your help. The problem was with operator precedence. Because "=" has a higher precedence over "or" in if statement the first if always evaluated to true. I resolved this now.
sony