如何编写可以测试正在使用的XQuery版本的XQuery?

时间:2013-12-30 23:25:37

标签: xquery saxon marklogic basex exist-db

我正在编写 XQuery ,需要检查正在运行的 XQuery 的版本(eXist,Saxon等)。是否有标准函数将返回 XQuery 的系统属性,例如版本,供应商等?

我知道有一些特定于系统的调用,例如eXist的

system:get-version()

但我正在尝试找到一个可以在所有平台上运行的标准函数。

例如,在 XSLT 中,我们有:

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')" />

他们的XQuery是否有类似的功能?

4 个答案:

答案 0 :(得分:2)

您可以使用XQuery 3.0函数function-lookup来检查是否存在特定于实现的函数来检查处理器。所有支持XQuery 3.0的处理器都应该能够处理它。

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()

不幸的是,我无法使用高阶函数使这更优雅,因为特定于实现的函数是在实际调用函数之前执行的。但我相信这也可以写得更优雅。

答案 1 :(得分:2)

在Saxon-HE的情况下Tricky,因为Saxon-HE仅支持XQuery 1.0并且不提供供应商扩展。但它确实提供了一种创建用户定义的扩展函数的机制,您可以使用它来实现您自己设计的疑问函数。

或者您可以定义外部全局变量并从运行查询的应用程序初始化该变量,假设应用程序在您的控制之下。

答案 2 :(得分:0)

Saxon似乎没有一个功能,但是eXist有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

此外,虽然您没有使用它,但其他SO读者可能有兴趣知道MarkLogic有xdmp:xquery-version()

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

答案 3 :(得分:0)

这里存在一个固有的问题,如果由不兼容的版本运行,不同版本的xquery根本不会编译。你通常不能做一个    #if版本&gt; 1
      新的东西    #其他      老东西    #ENDIF

某些供应商扩展提供了版本信息,您可以使用“eval()”类型的epression来解决这个问题,但在纯XQuery中,我无法想到可以用来做编译时有效的条件逻辑在当前版本上使用不同版本的某些功能。