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

标签 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>

最佳答案

处理组的默认顺序是“首次出现的顺序”:如果“London”作为分组键的第一次出现先于“Paris”的第一次出现,则具有键“London”的组会在分组键之前处理。带有键“Paris”的组。您可以使用 xsl:sort 作为 xsl:for-each-group 的子项来更改顺序。在这两种情况下,顺序不仅在指令的多次使用之间是稳定的,而且是在不同实现之间可预测和可互操作的。

我不确定我是否同意 @michael.hor257k 的观点,即两次进行相同的分组是一个坏主意。首先,在使用 map 迁移到 XSLT 3.0 之前,没有方便的数据结构来保存组。其次,这里存在内存与时间的权衡,因此这取决于您的情况。

在 3.0 中使用 map 执行此操作的方法是:

<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() 的处理顺序是不可预测的——但在多次调用中应该保持一致。

关于xslt - xsl for-each-group 的迭代顺序是否一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39360326/

相关文章:

function - 如何创建一个 xsl :function that returns a boolean

xslt - 如何遍历前面的 sibling 直到某个点

xml - 使用 group-by 对元素进行分组

javascript - 加载 xsl 时出错 "invalid xpath expression"

html - 参数和变量必须位于模板的顶部吗?

xml - 如何在 xslt 中使用 xpath 作为变量?

xml - 在 xslt 中使用正则表达式进行字符串的模式匹配

xml - 如何将 XML 文档的树结构分解为所需的结构..?

xslt - XSLT 中的子节点属性

xml - XSLT-搜索和查找特定标签