使用 xsl 流在 XSLT3 中分组,但出现 'Template rule is not streamable' 错误
Grouping in XSLT3 with xsl streaming, but getting 'Template rule is not streamable' error
请建议如何使用流选项 xslt3 进行分组。这里每个 Table 的总高度(按其 ID 分组,如果相同 table 信息重复)需要计算。
输入XML:
<AreaRoot>
<TableAndCaptionArea generated-by="table" id="t0005-tSC" height="90.488pt" display-role="block">
<a>One</a>
</TableAndCaptionArea>
<TableAndCaptionArea generated-by="table" id="t0005-tSC" height="33.3pt" display-role="block">
<a>Two</a>
</TableAndCaptionArea>
<TableAndCaptionArea generated-by="table" id="t0005-tDC" height="91.594pt" display-role="block">
<a>Three</a>
</TableAndCaptionArea>
<TableAndCaptionArea generated-by="table" id="t0005-tLS" height="91.594pt" display-role="block">
<a>Four</a>
</TableAndCaptionArea>
</AreaRoot>
XSLT 3.0:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<!--xsl:mode streamable="yes"/-->
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:fork>
<xsl:for-each-group select="descendant::*:TableAndCaptionArea[@id]" composite="yes" group-by="@id">
<table>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<!--Height of a table -->
<xsl:attribute name="height">
<xsl:variable name="var1">
<a>
<xsl:for-each select="current-group()/@height">
<b><xsl:value-of select="replace(., 'pt', '')"/></b>
</xsl:for-each>
</a>
</xsl:variable>
<xsl:value-of select="sum($var1/*:a/*:b)"/>
</xsl:attribute>
</table>
</xsl:for-each-group>
</xsl:fork>
</xsl:template>
</xsl:stylesheet>
在 运行 时出现错误:
Error on line 8 of Stream2.xsl:
XTSE3430: Template rule is not streamable
* The xsl:for-each-group/@select expression has crawling posture (that is, itcan select overlapping nodes)
所需结果:
<ATRinfo>
<height>
<table id="t0005-tSC" height="123.788"/>
<table id="t0005-tDC" height="91.594" />
<table id="t0005-tLS" height="91.594"/>
</height>
</ATRinfo>
使用SaxonEE9-9-0-2J版本。请建议如何解决错误。
由于要分组的元素看起来是兄弟,不需要后代轴找,可以用
<xsl:for-each-group select="/*/TableAndCaptionArea"
如果在您的实际数据中元素不是兄弟姐妹,并且出现在不同的级别,但不是递归嵌套,那么您也可以使用 innermost(//TableAndCaptionArea)
此外:您不需要 composite="yes" 因为@id 选择单个值
and: 高度的计算可以简化为:
<xsl:attribute name="height"
select="sum(current-group() ! number(replace(@height, 'pt', ''))">
在 (Martin Honnen Sir 的建议)的帮助下,我的程序稍微修改如下 [复制用法如下
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="/">
<xsl:element name="ATRinfo">
<xsl:fork>
<xsl:for-each-group select="copy-of(descendant::*:TableAndCaptionArea[@id])"
group-by="@id">
<table>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<!--Height of a table -->
<xsl:attribute name="height">
<xsl:variable name="var1">
<a>
<xsl:for-each select="current-group()/@height">
<b><xsl:value-of select="replace(., 'pt', '')"/></b>
</xsl:for-each>
</a>
</xsl:variable>
<xsl:value-of select="sum($var1/*:a/*:b)"/>
</xsl:attribute>
</table>
</xsl:for-each-group>
</xsl:fork>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请建议如何使用流选项 xslt3 进行分组。这里每个 Table 的总高度(按其 ID 分组,如果相同 table 信息重复)需要计算。
输入XML:
<AreaRoot>
<TableAndCaptionArea generated-by="table" id="t0005-tSC" height="90.488pt" display-role="block">
<a>One</a>
</TableAndCaptionArea>
<TableAndCaptionArea generated-by="table" id="t0005-tSC" height="33.3pt" display-role="block">
<a>Two</a>
</TableAndCaptionArea>
<TableAndCaptionArea generated-by="table" id="t0005-tDC" height="91.594pt" display-role="block">
<a>Three</a>
</TableAndCaptionArea>
<TableAndCaptionArea generated-by="table" id="t0005-tLS" height="91.594pt" display-role="block">
<a>Four</a>
</TableAndCaptionArea>
</AreaRoot>
XSLT 3.0:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<!--xsl:mode streamable="yes"/-->
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:fork>
<xsl:for-each-group select="descendant::*:TableAndCaptionArea[@id]" composite="yes" group-by="@id">
<table>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<!--Height of a table -->
<xsl:attribute name="height">
<xsl:variable name="var1">
<a>
<xsl:for-each select="current-group()/@height">
<b><xsl:value-of select="replace(., 'pt', '')"/></b>
</xsl:for-each>
</a>
</xsl:variable>
<xsl:value-of select="sum($var1/*:a/*:b)"/>
</xsl:attribute>
</table>
</xsl:for-each-group>
</xsl:fork>
</xsl:template>
</xsl:stylesheet>
在 运行 时出现错误:
Error on line 8 of Stream2.xsl:
XTSE3430: Template rule is not streamable
* The xsl:for-each-group/@select expression has crawling posture (that is, itcan select overlapping nodes)
所需结果:
<ATRinfo>
<height>
<table id="t0005-tSC" height="123.788"/>
<table id="t0005-tDC" height="91.594" />
<table id="t0005-tLS" height="91.594"/>
</height>
</ATRinfo>
使用SaxonEE9-9-0-2J版本。请建议如何解决错误。
由于要分组的元素看起来是兄弟,不需要后代轴找,可以用
<xsl:for-each-group select="/*/TableAndCaptionArea"
如果在您的实际数据中元素不是兄弟姐妹,并且出现在不同的级别,但不是递归嵌套,那么您也可以使用 innermost(//TableAndCaptionArea)
此外:您不需要 composite="yes" 因为@id 选择单个值
and: 高度的计算可以简化为:
<xsl:attribute name="height"
select="sum(current-group() ! number(replace(@height, 'pt', ''))">
在 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="/">
<xsl:element name="ATRinfo">
<xsl:fork>
<xsl:for-each-group select="copy-of(descendant::*:TableAndCaptionArea[@id])"
group-by="@id">
<table>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<!--Height of a table -->
<xsl:attribute name="height">
<xsl:variable name="var1">
<a>
<xsl:for-each select="current-group()/@height">
<b><xsl:value-of select="replace(., 'pt', '')"/></b>
</xsl:for-each>
</a>
</xsl:variable>
<xsl:value-of select="sum($var1/*:a/*:b)"/>
</xsl:attribute>
</table>
</xsl:for-each-group>
</xsl:fork>
</xsl:element>
</xsl:template>
</xsl:stylesheet>