Question

I am writing an XQuery that needs to check what version of XQuery is being run (eXist, Saxon, etc.). Is there a standard function that will return the system properties of an XQuery such as version, vendor etc?

I know there are some system specific calls such as eXist's

system:get-version()

but I am trying to find a standard function that would run on all platforms.

For example in XSLT we have:

Version:
<xsl:value-of select="system-property('xsl:version')" />
<br />
Vendor:
<xsl:value-of select="system-property('xsl:vendor')" />
<br />
Vendor URL:
<xsl:value-of select="system-property('xsl:vendor-url')" />

Are their similar functions for XQuery?

Was it helpful?

Solution

You can use the XQuery 3.0 function function-lookup to check the existence of implementation-specific functions to check for the processors. All XQuery 3.0 supporting processors should be able to process this.

declare function local:exist() as xs:boolean {
  try {
    if (not(empty(function-lookup(xs:QName('system:get-version'), 0))))
    then true()
    else false()
  } catch * {
    false()
  }
};

(: works only on Saxon PE and EE, fails in HE since HE does not support XQuery 3.0. It would be nice if saxon had a version function. :)
declare function local:saxon() as xs:boolean {
  try {
    if (not(empty(function-lookup(xs:QName('saxon:parse'), 1))))
    then true()
    else false()
  } catch * {
    false()
  }
};

declare function local:marklogic() as xs:boolean {
  try {
    if (not(empty(function-lookup(xs:QName('xdmp:xquery-version'), 0))))
    then true()
    else false()
  } catch * {
    false()
  }
};

declare function local:basex() as xs:boolean {
  try {
    if (not(empty(function-lookup(xs:QName('prof:time'), 1))))
    then true()
    else false()
  } catch * {
    false()
  }
};

declare function local:get-processor() as xs:string {
  if (local:exist()) then "eXist"
  else if (local:saxon()) then "Saxon"
  else if (local:marklogic()) then "MarkLogic"
  else if (local:basex()) then "BaseX"
  else "Unknown"
};

local:get-processor()

Unfortunately, I was not able to make this more elegant using Higher-Order functions, as the implementation-specific functions were executed before the function is actually called. But I am sure this could also be written more elegant.

OTHER TIPS

Tricky in the case of Saxon-HE because Saxon-HE only supports XQuery 1.0 and provides no vendor extensions. It does however provide a mechanism for creating user-defined extension functions, and you could use that to implement an interrogative function of your own design.

Or you could define an external global variable and initialize that from the application that runs the query, assuming the application is under your control.

There doesn't appear to be a function in Saxon, but eXist has system:get-version():

http://exist-db.org/exist/apps/fundocs/view.html?uri=http://exist-db.org/xquery/system&location=java:org.exist.xquery.functions.system.SystemModule

Also, although you're not using it, other SO readers may be interested to know that MarkLogic has xdmp:xquery-version():

http://docs.marklogic.com/7.0/xdmp:xquery-version

There is an inherent problem here that different versions of xquery simply wont complile if run by an incompatible version. You cant generally do a
#if version > 1
new stuff #else old stuff #endif

Some vendor extensions supply version information and you can use an "eval()" type epression to get around this, but in pure XQuery there is no point I can think of that can used to do conditional logic that is compilation time valid on the current version yet use some feature on a different version.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top