xsl:在 for-each-group() 中排序
Posted
技术标签:
【中文标题】xsl:在 for-each-group() 中排序【英文标题】:xsl:sort inside for-each-group() 【发布时间】:2016-04-09 23:38:30 【问题描述】:由于某种原因,自升级到 Saxon 9.7.0.1 后,for-each-group 中的 xsl:sort 引发异常
XML-
<table class="vv">
<tr><td>woot1</td><td>woot2</td></tr>
<tr><td>woot1</td><td>woot2</td></tr>
<tr><td>woot1</td><td>woot2</td></tr>
<tr><td>woot1</td><td>woot2</td></tr>
</table>
XSL-
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="table[@class='vv']">
<div class="row">
<xsl:for-each-group select="tr" group-by="td[1]/text()">
<xsl:sort/>
test
</xsl:for-each-group>
</div>
</xsl:template>
错误-
只是想验证这是否是 Saxon 中的错误,或者在 XSLT 3.0 中过去的工作方式发生了变化
【问题讨论】:
我可以用 9.7 EE 重现问题,但不能用 PE 或 HE。你也在用 EE 吗? 【参考方案1】:IncompatibleClassChangeError
通常意味着 JVM 在运行时加载了一个类,这与它在编译时的方式不同。也就是说,代码是使用类路径编译的,其中包含与运行时加载的版本不同的某个库类的版本。
两种可能的研究理论:
(a) 在这种情况下,从表面上看,所涉及的所有类似乎都是 Saxon 类,因此这可能表明您在类路径上有多个 Saxon 版本,并且由于某种原因代码正在从两者加载。
(b) 另一方面,我可以在您的屏幕截图的底部看到一半被裁剪的行,这表明您正在使用启用了字节码生成的 Saxon-EE,这可能表明存在错误在字节码生成中。尝试禁用字节码生成以查看问题是否消失。例如通过调用Processor.setConfigurationProperty(FeatureKeys.GENERATE_BYTECODE, false)
。
如果确实是字节码生成错误,请将其记录在http://saxonica.plan.io,以便我们可以正确跟踪。我们几乎可以肯定需要访问一个样式表来演示这个问题。
【讨论】:
感谢您的回复。刚刚验证项目中只使用了一个 Saxon jar。我们正在检查是否启用了字节码生成。 原来我们启用了字节码生成。如果我们禁用它,它就会消失。这是问题-saxonica.plan.io/issues/2573【参考方案2】:我不认为这是一个真正的修复,但是,奇怪的是,您可以在 for-each-group 正文中添加 <xsl:value-of select="current-grouping-key()"/>
语句,异常就会消失。可以在评论中。
<xsl:template match="table[@class='vv']" mode="copy">
<div class="row">
<xsl:for-each-group select="tr" group-by="td[1]/text()">
<xsl:sort/>
<xsl:comment><xsl:value-of select="current-grouping-key()"/></xsl:comment>
test
</xsl:for-each-group>
</div>
</xsl:template>
【讨论】:
其实一点也不神秘。对样式表的微小更改可能会使优化器走上完全不同的道路,从而导致执行计划大不相同。这就是为什么我们通常需要一个实际演示问题的重现,而不仅仅是一个代码 sn-p。 (感谢提供一个)。 虽然这种情况的原因很有趣,并且在 Saxon 错误条目中进行了讨论。以上是关于xsl:在 for-each-group() 中排序的主要内容,如果未能解决你的问题,请参考以下文章
来自变量的 XSLT for-each-group 不起作用
如何使用 Apache Camel 在 XSLT 中为每个组申请