XSLT 2.0 产生错误:“上下文项未定义”

Posted

技术标签:

【中文标题】XSLT 2.0 产生错误:“上下文项未定义”【英文标题】:XSLT 2.0 produces error: "the context item is undefined" 【发布时间】:2012-04-22 13:48:08 【问题描述】:

我们使用生成 XSLT 2.0 文件的 Altova Stylevision。我们使用 Saxon 9 for Java 来执行这些 XSLT 文件。这几年来一直运行良好,可惜我们都没有真正了解 XSLT。

现在我们有错误:

Error at /xsl:stylesheet/xsl:function[9]
XPDY0002: Axis step child::element(item, xs:anyType) cannot be used here:
  the context item is undefined

第9个函数是:

<xsl:function name="sps:GoogleChartDataSourceUnitCount" as="xs:string">
  <xsl:sequence select="concat(string-join(item/string(if ( number($XML/report/calculation-data[@data-source-name = $DataSourceParent]/item/variable[@name=&apos;unit_count&apos;]/@value) &lt; 0 ) then 0 else round-half-to-even(number(variable[@name=&apos;unit_count&apos;]/@value),2)),&apos;,&apos;),&apos;&amp;chxl=0:|&apos;,string-join(item/variable[@name=&apos;month&apos;]/@value,&apos;|&apos;),&apos;|2:||Min&amp;chds=0,&apos;,string(round-half-to-even( max(item/(number(variable[@name=&apos;unit_count&apos;]/@value)))+1 , 0 )),&apos;&amp;chxr=1,0,&apos;,string(round-half-to-even( max(item/(number(variable[@name=&apos;unit_count&apos;]/@value)))+1 , 0 )))"/>
</xsl:function>

有人知道发生了什么吗?

【问题讨论】:

【参考方案1】:

您可能会在不同的用例中遇到此问题。 对我来说,由于我忘记在函数中的参数之前放置美元 ($) 符号, 所以处理器认为我正在使用节点标签而不指示上下文,然后给出这个错误。 我只需要将 $ 放在我的参数之前。 希望我的解决方案对其他人有所帮助。

【讨论】:

【参考方案2】:

根据W3C XSLT 2.0 specification,xsl:function 的初始上下文项未定义

这意味着在函数体内对数据(项)的任何引用只能发生在参数(传递的或全局的)或变量之外。

问题是提供的代码中的表达式以开头:

concat(string-join(item ...

这显然违反了上述规则——item 是从上下文项中引用的,这在 xsl:function 中是不允许的。

解决方案

    将预期的上下文项作为参数传递(推荐),例如命名为pDoc,或者让一个全局变量/参数包含预期的上下文项。

    在 XPath 表达式的第一个定位步骤中从该参数/变量中引用项目,例如 $pDoc/item

常见问题解答:为什么会有这个限制?

答案:不允许隐式初始上下文项使得 XSLT 处理器可以执行更广泛的静态分析并更积极地优化代码。

【讨论】:

【参考方案3】:

问题在于该函数使用像item这样的路径表达式,它需要一个上下文项作为the specification mandates“在样式表函数的主体中,焦点最初是未定义的;这意味着任何引用上下文项的尝试、上下文位置或上下文大小是不可恢复的动态错误。[XPDY0002]"。因此,该函数需要有一个参数来传递应该应用路径的节点或节点序列,例如

<xsl:function name="sps:GoogleChartDataSourceUnitCount" as="xs:string">
  <xsl:param name="nodes"/>
  <xsl:sequence select="concat(string-join($nodes/item/string(...)))"/>
</xsl:function>

然后需要调用例如sps:GoogleChartDataSourceUnitCount(.).

如果样式表是由 Altova 的某些工具生成的,您可能需要在 Altova forums 中询问这是否是一个已知问题以及是否有可用的修复程序。

【讨论】:

以上是关于XSLT 2.0 产生错误:“上下文项未定义”的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 不支持 XSLT 2.0

XSLT 2.0 中的尾递归函数不起作用

在 .NET XSLT 中使用 document() 函数会产生错误

XSLT 2.0 - 如何用字符串替换'('和')'来清空?

将 XSLT 1.0 升级到 XSLT 2.0

xslt 2.0:使用HashMap