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)
Related
How to call a custom xquery function in exist-db using the REST API ?
Is it possible to have more than 1 function in the xquery file ?
declare function local:toto() as node() {
return doc("/db/ProjetXML/alice.xml")/raweb/identification/projectName)
};
declare function local:pomme() as node() {
return doc("/db/ProjetXML/carmen.xml")/raweb/identification/projectSize);
};
If I call it using :
http://localhost:8080/exist/rest/db/ProjetXML/orange.xqy?_query=local:toto()
I get the following error :
err:XPST0017 Call to undeclared function: local:toto [at line 1, column 1, source: local:toto()]
Your help is appreciated.
You have syntax errors in your XQuery:
You have two functions named local:toto(). Each function must have a distinct name.
There is no semicolon following the function definition, i.e. } should be };.
Also you should remove the return expression, as there is no preceding binding.
Another option would be to parameterize the input file, e.g.:
import module namespace request="http://exist-db.org/xquery/request";
declare function local:toto($name as xs:string) as node() {
let $doc :=
if($name eq "carmen")then
doc("/db/ProjetXML/carmen.xml")
else
doc("/db/ProjetXML/alice.xml")
return
$doc/raweb/identification/projectName);
};
local:toto(request:get-parameter("name", "alice"))
You can then call this via the REST Server using a URL like:
http://localhost:8080/exist/rest/db/ProjetXML/orange.xqy?name=carmen
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
I'm trying to replace two backslashes with a single one within Oracle Service Bus xquery transformation with the replace function:
let $str := replace($srcStr, "\\\\", "\\"), where $srcStr holds the value "^\\d{1,4}$"
But for some reason this does not work. The result is stil "^\\d{1,4}$"
When I'm calling the same function in e.g. Altova XmlSpy this works fine: replace("^\\d{1,4}$", "\\\\", "\\") results in ^\d{1,4}
Does anybody have an idea why OSB does not match the backslashes in the source string? What could be a workaround?
This is a bug.
You can write custom regexp to workaround this bug.
declare function xf:replace_test($e as element()) as xs:string {
let $str := replace("junk (\)\ junk", ".*\\.*", "\$1")
return $str
};
declare variable $e as element() external;
xf:replace_test($e)`
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)
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.