3

我正在编写一个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

4 回答 4

2

Saxon-HE 的情况很棘手,因为 Saxon-HE 仅支持 XQuery 1.0 并且不提供供应商扩展。然而,它确实提供了一种用于创建用户定义的扩展功能的机制,您可以使用它来实现您自己设计的询问功能。

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

于 2014-01-01T10:01:47.183 回答
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()

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

于 2013-12-31T11:46:05.637 回答
0

这里有一个固有的问题,即如果由不兼容的版本运行,不同版本的 xquery 根本无法编译。你通常不能做
#if 版本 > 1 个
新东西 #else old stuff #endif

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

于 2013-12-31T20:51:11.930 回答
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

于 2013-12-30T23:59:20.510 回答