xsl for-each-group的迭代顺序是否一致?

时间:2016-09-07 02:20:35

标签: xslt xslt-2.0

for-each-group中的迭代顺序是否可以使用相同的数据进行预测?或者如果同一个循环执行两次,它会改变,例如我在模板的不同部分重复两次这个循环:

<xsl:for-each-group
            select="descendant::FormSectionElements[not(LoadBindBase = '')]" 
            group-by="LoadBindBase">

... first ...

</xsl:for-each-group>


<xsl:for-each-group
            select="descendant::FormSectionElements[not(LoadBindBase = '')]" 
            group-by="LoadBindBase">

... second ...

</xsl:for-each-group>

2 个答案:

答案 0 :(得分:2)

处理组的默认顺序是&#34;首次出现的顺序&#34;:如果第一次出现&#34;伦敦&#34;作为分组键出现在&#34; Paris&#34;的第一次出现之前,然后是关键&#34;伦敦&#34;使用密钥&#34; Paris&#34;在组之前处理。您可以使用xsl:sort更改顺序作为xsl:for-each-group的子项。在这两种情况下,顺序不仅在指令的多次使用之间是稳定的,而且在不同的实现之间是可预测的和可互操作的。

我不确定我会同意@ michael.hor257k两次做同样的分组是个坏主意。首先,在使用地图移动到XSLT 3.0之前,没有方便的数据结构来保存组。其次,这里有记忆时间的权衡取决于你的情况。

使用3.0中的地图执行此操作的方法是:

<xsl:variable name="groups" as="map(xs:string, node()*)">
  <xsl:map>
    <xsl:for-each-group
         select="descendant::FormSectionElements[not(LoadBindBase = '')]">
      <xsl:map-entry key="current-grouping-key()" select="current-group()"/>
    </xsl:for-each-group>
  </xsl:map>
</xsl:variable>

然后你可以使用例如:

迭代这些组
<xsl:for-each select="map:keys($groups)">
  <group key="{.}">
    <xsl:apply-templates select="$groups(.)" mode="xxx"/>
  </group>
</xsl:for-each>

map:keys()的处理顺序是不可预测的 - 但它应该在多个调用中保持一致。

答案 1 :(得分:1)

  1. 组之间的顺序在XSLT 2.0规范中定义,并且每次使用相同的填充调用xsl:for-each-group指令时都是相同的(除非您使用xsl:sort显式更改它)。

  2. 分组操作可能很昂贵,建议您只执行一次。如有必要,您可以将分组的整个结果(或仅其一些特征,如discussed in your previous question)放在变量中,以便以后重复使用。

  3. P.S。请参阅:http://xyproblem.info/