Need a way to backport serialize() to xquery1.0 - xquery

I'd like to put an xml node as CDATA in the output document and I have to use xquery1.0
How can I backport serialize()?
I have Saxon-HE-9.5.1-8.jar as XQuery processor provided by wso2-mi

I don't know details about Saxon 9.5 but it is not an old, pure XQuery 1.0 processor but somewhere between the two versions; so perhaps trying
xquery version "3.0";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method 'xml';
declare option output:cdata-section-elements 'foo';
works.

Related

How do I get the HTTP POST body in MarkLogic XQuery?

I'm trying to use the exist-db request:get-data() method to get the post data of a request. However, I'm getting the error:
XDMP-UNDFUN: (err:XPST0017) Undefined function request:get-data()
I did declare the namespace in my header. I don't understand why I still can't use request:get-data() or any of the other request: functions
declare namespace request="http://exist-db.org/xquery/request";
declare option exist:serialize "method=xml media-type=text/xml indent=yes";
let $post-data := request:get-data()
return $post-data
I think you're looking for xdmp:get-request-body.
Sam pointed you to the function you need, but I wanted to respond to another part of your question:
I did declare the namespace in my header. I don't understand why I still can't use request:get-data() or any of the other request: functions
Each XQuery processing engine implements standard functions, but there is other functionality needed that is not defined by the standard. For MarkLogic, you'll use standard functions with the fn: prefix.
Each XQuery engine then defines additional functions that will be needed. For Exist DB, some of those are in the "http://exist-db.org/xquery/request" namespace, while MarkLogic uses "http://marklogic.com/xdmp" for a lot of its extension functions.
When you're looking for the MarkLogic equivalent of an Exist DB-specific function, search on http://docs.marklogic.com -- start with the function name, and if that doesn't work, search for the terms that describe what you're trying to do.

Difference between importing and declaring module namespace in XQuery?

What is the difference between the following:
import module namespace fs = "http://expath.org/ns/file";
declare namespace an = "http://zorba.io/annotations";
How does "import module namespace" compare to "declare namespace"?
And more over, with namespace decalaration waht is the difference between
declare namespace an = "http://zorba.io/annotations";
and
module namespace an = "http://zorba.io/annotations";
The module namespace will allow you to use xquery functions from various modules. This is like using libraries in other languages. For example the functx library:
import module namespace functx="http://www.functx.com"
functx:substring-before-match('abc-def-ghi', '[dg]')
If you would want to create your own module, 'mymodule.xq' you would begin the file with a module declaration:
module namespace mymodule = "http://example.org/mymodule";
declare function mymodule:myfunc()....
declaring namespaces allows you to create and query xml elements using different namespaces.
For example:
declare namespace x="http://some.random.namespace";
//x:someelement[. = 'hello world']
will query xml elements that have the 'x' namespace.
Now in your case regarding the zorba annotations. Declaring a namespace is really just saying to the xquery processor: this prefix (an) is bound to this namespace (http://zorba.io/annotations). I'm not really sure how to explain it further, it just the way it has been defined in the xquery spec. It's just to tell the xquery processor that if you type:
declare %an:nondeterministic function random:random() as xs:integer external;
that 'an' is bound to 'http://zorba.io/annotations' which is something that zorba will understand.
You might just as well change 'an' to 'foo':
declare namespace foo = "http://zorba.io/annotations";
declare %foo:nondeterministic function random:random() as xs:integer external;
and zorba would still be able to understand it.

Indentity Transform with Namespaces

There is a well known Identity Transform sample code in the XQuery wikibook
But it works well only with no namespace documents, or explicitly declaring the namespaces with the same prefixes used in the document about to be processed.
If you don't declare the namespaces (with the same prefixes), you get an error:
Cannot compile xquery: err:XPST0081 No namespace defined for prefix
xsd [at line 15, column 12]
is there a way to write an Identity Transform in XQuery, that can automatically handle the namespaces and prefixes, avoiding the explicit declaration of namespaces?
EDIT:
This is the code from the Wikibook:
(: return a deep copy of the element and all sub elements :)
declare function local:copy($element as element()) as element() {
element {node-name($element)}
{$element/#*,
for $child in $element/node()
return
if ($child instance of element())
then local:copy($child)
else $child
}
};
In my case, I don't know the namespaces or prefixes in the document to be processed, so the element { } { } construct fails if the namespace and prefix are not declared in the XQuery.
To reproduce it, just copy/paste and run it with a document that uses prefixed namespaces.
I think the answer is no. If you want to process namespaced elements, then those namespaces need to be declared.
Based on the error message, all you need to do is declare the xsd namespace at the top of your XQuery document.
Declare namespace xsd="http://www.w3.org/2001/XMLSchema";
If this doesn't do it, then posting your XQuery would greatly help us understand what the issue is.

How do i generate a random UUID in xquery

Can anyone help me with this one? I want to be able to generate a random UUID in x-query. Is there any function to do this?
thanks!
Using Saxon, you should be able to link to Java to generate the UUIDs like this:
XSLT
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:uuid="java:java.util.UUID">
XQuery
declare namespace uuid = "java:java.util.UUID";
Then call the function uuid:randomUUID() anywhere in the stylesheet or XQY script.
fn-bea:uuid() is also an option for those who use BEA's xQuery implementation.
For example, when writing xQuery for Oracle Service Bus (OSB) Framework.

How to set the default / base collection of a XQJ Connection

I want to query the eXist db via the XQJ API. Therefore I have an XQuery file which I want to apply to several different documents inside different collections of the database.
My question is, how can I set the path to the document/collection? I want to apply the XQuery only on specific documents/collections and canĀ“t set the path directly in the XQuery document (with the doc('path/to/doc') function ), because I want to apply the same XQuery to several files with different paths.
I could bind a Java variable to an Xquery expression but there has to be a more elegant way to achieve this task with the XQJ API. Hope you can help me out a little bit.
If you know the specific document URIs up-front, you could bind a bunch of URIs as a xs:string sequence, where you can then iterate through them in your XQuery expression, performing operations against each URI as necessary.
declare variable $uris as xs:string* external;
for $uri in $uris
return (
(: perform operation against $uri :)
)
Or if you know the collection uri,
declare variable $collection-uri as xs:string external;
for $document-node in fn:collection($collection-uri)
return (
(: perform operation against document-node() :)
)
In a future version of eXist XQJ API, you will be able to set a collection as the default context, which goes against both the XQJ standard AND the XQuery 1.0 / 3.0 standards but other users appear to be wanting this functionality quite badly.

Resources