Saxon HE and XQuery: Unexpected token "<eof>" - xquery

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

Related

Calling JAVA Method from XQuery

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)

MarkLogic xquery errors

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.

XQuery Nested loop error

I'm using OSM 7.2.0.3 and I have cartridge with an Order Recognition Rule, with its Order Data Rule (inside Transformation tab)
In the ODR I have this XQuery code:
declare namespace im="http://xxx";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare variable $order := fn:root(.)/im:Order;
<_root>
<Order>
{
for $moli in $order/MainOrderLineItem
return {
<OrderLineItem>
{$moli/LineItemAttributeInfo/LineItemAttribute}
</OrderLineItem>
{
for $oli in $moli/OrderLineItem
return
<OrderLineItem>
{$oli/LineItemAttributeInfo/LineItemAttribute}
</OrderLineItem>
}
}
}
</Order>
</_root>
There's no compile error in OSM, but on runtime I get:
Invalid Order Specification Fault
Order data expression failed due to oracle.communications.ordermanagement.rule.XMLRuleException
I run the OSM by submitting an XML through Web Service.
Thanks a lot for your replies.
The returned XML should actually be in parentheses instead of braces. There also needs to be a comma between the first returned OrderLineItem element and the FLWOR expression instead of wrapping it in braces:
declare namespace im="http://xxx";
declare namespace xs="http://www.w3.org/2001/XMLSchema";
declare variable $order := fn:root(.)/im:Order;
<_root>
<Order>{
for $moli in $order/MainOrderLineItem
return (
<OrderLineItem>
{$moli/LineItemAttributeInfo/LineItemAttribute}
</OrderLineItem>,
for $oli in $moli/OrderLineItem
return
<OrderLineItem>
{$oli/LineItemAttributeInfo/LineItemAttribute}
</OrderLineItem>
)
}</Order>
</_root>

To remove the node but keep the value inside intact through XQuery

I have a content.xml modelled as below
<root>
<childnode>
Some text here
</childnode>
</root>
I am trying to remove the <childnode> and update the content.xml with only the value of it
so the output looks like
<root>
Some Text here
</root>
I wrote a function to perform this but anytime I run it it gives me error as "unexpected token: modify". I was thinking of a way to accomplish this without using functx functions.
xquery version "1.0";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace file="http://exist-db.org/xquery/file";
declare namespace system="http://exist-db.org/xquery/system";
declare namespace util="http://exist-db.org/xquery/util";
declare namespace response="http://exist-db.org/xquery/response";
declare function local:contentUpdate() {
let $root := collection('/lib/repository/content')//root/childNode
let $rmChild := for $child in $root
modify
(
return rename node $child as ''
)
};
local:updateTitle()
Thanks in advance
There are multiple problems with your query:
Updating functions must be declared as updating.
You're calling another function than you defined (probably you didn't notice as there still have been syntax errors).
Rename node expects some element (or processing instruction, attribute) as target, the empty string is not allowed.
At least BaseX doesn't allow updating statements when defining code as XQuery 1.0. Maybe exist doesn't care about this, try adding it if you need to know.
You do not want to rename, but replace all <childnode />s with its contents, use replace node.
This code fixes all these problems:
declare updating function local:contentUpdate() {
let $root := collection('/lib/repository/content')
return
for $i in $root//childnode
return
replace node $i with $i/data()
};
local:contentUpdate()
eXist-db's XQuery Update syntax is documented at http://exist-db.org/exist/update_ext.xml. Note that this syntax predates the release of the XQuery Update Facility 1.0, so the syntax is different and remains unique to eXist-db.
The way to do what you want in eXist-db is as follows:
xquery version "1.0";
declare function local:contentUpdate() {
let $root := doc('/db/lib/repository/content/content.xml')/root
return
update value $root with $root/string()
};
local:contentUpdate()
The primary changes, compared to your original code, are:
Inserted the eXist-db syntax for your update
Prepended '/db' to your collection name, as /db is the root of the database in eXist-db; replaced the collection() call with a doc() call, since you stated you were operating on a single file, content.xml
Changed //root to /root, since "root" is the root element, so the // (descendant-or-self) axis is extraneous
Replaced updateTitle() with the actual name of the function, contentUpdate
Removed the extraneous namespace declarations
For more on why I used $root/string(), see http://community.marklogic.com/blog/text-is-a-code-smell.

xquery - expected return found let

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)

Resources