I get this error from Saxon,
Engine name: Saxon-PE XQuery 9.2.1.2
Severity: fatal
Description: XQuery syntax error in #... (:return :) let $#: expected "return", found "let"
Start location: 776:0
on this function
declare function local:set-internet-type($req1 as element(ns0:req), $cate as element()) as xs:string {
if(count( for $itm in $req/*:cust/*:inter/*:itm
where $789/*:product/*:030/*:specs/*:name/text()= data($11/INTERNET)
and $22/*:action/text()="CHANGE"
return $33)>0) then
(
for $44 in $55
where $tt/*:name/text()= data($t/INTERNET)
and $u/*:action/text()="CHANGE"
(:return <fake/>:)
let $z:= $a/*:product/*:c/*:e[1]
return concat($x,'>',$y)
) else ("")
};
I am new with xquery and I spent a lot on this error without getting a solution. Vars were masked intentionally but from the error message seems something related to the function flow.
Any help is appreciated.
Thanks in advance
Alessandro
Saxon only declares to have "partial support of XQuery 1.1". Therefore, I guess, it supports the old FLWOR format in which you cannot use let after where. Just try to swap these clauses:
for $44 in $55
let $z:= $a/*:product/*:c/*:e[1]
where $tt/*:name/text()= data($t/INTERNET)
and $u/*:action/text()="CHANGE"
return concat($x,'>',$y)
Related
I am trying to call a JAVA method from XQuery. But it is failing
I have declared the class like:
declare namespace b64 = "java:java.util.Base64";
And I am calling it like:
(: Encode a string into Base64 :)
declare function javautil:encodebase64($in as xs:string) as xs:string {
b64:getEncoder().encodeToString($in)
};
(: Decode a string from Base64 :)
declare function javautil:decodebase64($in as xs:string) as xs:string {
b64:getDecoder().decode($in)
};
But I get the error:
XPST0003: XQuery syntax error in #...64:getEncoder().encodeToString#:
expected "}", found "."
I am not sure if its a syntax problem or something else. I looked for examples on Google. But most of them are restricted to a single method call. Not chained method like getEncoder().encodeToString(). Any help would be appreciated. Thanks!
You're confusing Java syntax with XQuery syntax - there's no "." operator in XQuery.
In XQuery 1.0 I would expect to see b64:decode(b64:getDecoder(), $in), or in XQuery 3.1 b64:getDecoder() => b64:decode($in)
I copy paste this example from http://www.w3schools.com/xquery/xquery_functions.asp (though I added the namespace declaration):
declare namespace local="local";
declare function local:minPrice($p as xs:decimal?,$d as xs:decimal?) as
xs:decimal? {
let $disc := ($p * $d) div 100
return ($p - $disc)
};
But when I try to run it, the SAXON output is:
Error on line 6 column 1 of newq.xq:
XPST0003 XQuery syntax error near #...v 100 return ($p - $disc) };#:
Unexpected token "<eof>" in path expression
Static error(s) in query
Anyone idea? Bug in SAXON, or is it using another syntax?
Definitely not a Saxon bug. The reason for the error is the only thing in your XQuery is a function declaration; there is no expression. You're only allowed to do this if you declare it as a module.
Otherwise you'll actually have to do something in the XQuery...
declare namespace local="local";
declare function local:minPrice($p as xs:decimal?, $d as xs:decimal?) as xs:decimal? {
let $disc := ($p * $d) div 100
return ($p - $disc)
};
(:Do something...:)
local:minPrice(10,10)
Results of running this XQuery (using Saxon 9):
9
Both following queries run fine on eXist-db but produce the following errors on MarkLogic server. Any help appreciated.
Query:
for $cust in //Customer[#id=1011]
for $ord in //Order[#Acct = $cust//Accounts//Account/#id/fn:string(.)]
return $ord/OrdQty/#Cash
return max($orderprice)
Error:
[1.0-ml] XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected Return_, expecting $end or SemiColon_
Stack Trace
At line 10 column 0:
In xdmp:eval("xquery version "1.0-ml";
declare namespace html = ...", (), 13899855847338100900different-tr...)
8.
9. return $ord/OrdQty/#Cash
10. return max($orderprice)
Query:
for $cust in //Customer
return <Customer>
{$cust/#id}
{$cust/Name}
<Customer_Securities>
{for $account in $cust/Accounts/Account
return <Account BALANCE="{$account/Balance/OnlineActualBal}"
ACCOUNT_ID="{$account/#id}">
<Securities>
{$account/Holdings/Position/Name}
</Securities>
</Account> }
</Customer_Securities>
</Customer>
Error:
[1.0-ml] XDMP-EXPNTREECACHEFULL: for $cust in fn:collection()/descendant::Customer return { $cust/#id }{ $cust/Name }{ for $account in $cust/Accounts/Account return { $account/Holdings/Position/Name } } -- Expanded tree cache full on host gkomninos-pc.studentcom.co.uk
Stack Trace
At line 3 column 0:
In xdmp:eval("xquery version "1.0-ml";
declare namespace html = ...", (), 13899855847338100900different-tr...)
1. xquery version "1.0-ml";
2. declare namespace html = "http://www.w3.org/1999/xhtml";
3. for $cust in //Customer
4.
5. return
For the first error, that may be related to some additional syntax leeway provided by eXist; however, the for shouldn't have two returns (see XQuery spec on FLWORs) (also $orderprice is not defined):
for $cust in //Customer[#id=1011]
for $ord in //Order[#Acct = $cust//Accounts//Account/#id/fn:string(.)
return ($ord/OrdQty/#Cash, max($orderprice))
The second query is throwing an exception because it selects too much data to fit into the expanded tree cache. This will be dependent on the number of customers in your database. Is it possible to select fewer customers (i.e.: maybe this report only needs to select those with overdue balances, etc.)? Alternatively, you can generate your report in batches to avoid filling the cache.
My code is working fine if I don't use function.
declare function local:samlefamily(
$pers as xs:string?) as xs:string?
{
some stuff
};
if (exists(/*/FamilyRec/Child/Link[#Ref = "IN0099"]))
then
for $family in doc("family.xml") /*/FamilyRec
where $family/Child/Link[#Ref = "IN0099"]
return if (local:samlefamily(data($family/HusbFath/Link/#Ref))) then local:samlefamily(data($family/HusbFath/Link/#Ref)) else "na1"
else "na2"
But problem occurs when I tried to define function
declare function local:giveParent($pers as xs:string) as xs:string
{if (exists(/*/FamilyRec/Child/Link[#Ref = $pers]))
then
for $family in doc("gedcom.xml") /*/FamilyRec
where $family/Child/Link[#Ref = $pers]
return if (local:samlefamily(data($family/HusbFath/Link/#Ref))) then local:samlefamily(data($family/HusbFath/Link/#Ref)) else "na1"
else "na2"
};
I am getting error:
Description: Unexpected token "< eof >" in path expression
It is not occurring for passing parameter($pers). Even I use static ("IN0099") parameter to it, same error I am getting.
Can anyone please help? Can't I use If ... else in user defined function? Advanced thanks for your support
You need to have at least one non-function statement in the xquery file, i.e. add anything after the last semicolon
Otherwise your code looks fine
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
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.