每个组属性的 XSLT2 上下文
XSLT2 context for for-each-group attributes
我对 XSLT1 相当有经验,并且已经开始使用 XSLT2。大多数更改都很容易理解,但我在理解 xslt2 中如何评估 for-each-group 元素上的属性时遇到了一些困难。假设我有以下输入文档
<root>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<notanitem>abc</notanitem>
<item>6</item>
<item>7</item>
</root>
以下样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<result>
<xsl:for-each-group select="root/item" group-by="(position() - 1) idiv 3">
<row>
<xsl:for-each select="current-group()">
<cell><xsl:value-of select="."/></cell>
</xsl:for-each>
</row>
</xsl:for-each-group>
</result>
</xsl:template>
</xsl:stylesheet>
将 items 分组为 rows,每个 3 cells,产生
<result>
<row>
<cell>1</cell>
<cell>2</cell>
<cell>3</cell>
</row>
<row>
<cell>4</cell>
<cell>5</cell>
<cell>6</cell>
</row>
<row>
<cell>7</cell>
</row>
</result>
因此只有 item 个元素被计算在分配位置中。
现在,如果我将 for-each-group 更改为使用 group-starting-with="*[position() mod 3 = 1]"
。我在第一行得到项目 1、2 和 3;第二行第 4 项和第 5 项;第三行中的第 6 项和第 7 项(因此 notanitem 元素被计算在分配位置中)。
似乎在第一种情况下,位置函数只对项目进行评估,而在第二种情况下,位置函数是在整个文档(或根元素下的子元素)上进行评估。
是这样吗? group-by
评估仅限于 仅 到由 for-each-group 构造实际选择的项目,但 group-starting-with
评估基于整个子树这些元素在(包括未选择的元素)?评估这两个属性的上下文是什么?
我觉得我对这些工作原理几乎有了正确的想法,但这让我感到困惑,因为我不太清楚在规范中解释这个的正确方法,以及我看过的其他问题'似乎在询问或回答这个问题。
group-by
是一个计算分组键的表达式,但是 group-starting-with
是一个模式(您从 XSLT 1.0 知道 match
属性 xsl:template
或xsl:key
).
如果您改用 group-starting-with="item[position() mod 3 = 1]"
,那么您会看到与 group-by
.
相同的结果
至于group-by
的评价,见https://www.w3.org/TR/xslt20/#grouping里面说的
When calculating grouping keys for an item in the population, the
expression contained in the group-by or group-adjacent attribute is
evaluated with that item as the context item, with its position in
population order as the context position, and with the size of the
population as the context size. The resulting sequence is atomized,
and each atomic value in the atomized sequence acts as a grouping key
for that item in the population.
population
https://www.w3.org/TR/xslt20/#dt-population定义为for-each-group select="expression"
选择的序列:
[Definition: The sequence of items to be grouped, which is referred to
as the population, is determined by evaluating the XPath expression
contained in the select attribute.]
至于在 group-starting-with
的模式中调用 position()
,您首先需要查看模式,显然 *
匹配所有元素,而不仅仅是 item
元素。
我对 XSLT1 相当有经验,并且已经开始使用 XSLT2。大多数更改都很容易理解,但我在理解 xslt2 中如何评估 for-each-group 元素上的属性时遇到了一些困难。假设我有以下输入文档
<root>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<notanitem>abc</notanitem>
<item>6</item>
<item>7</item>
</root>
以下样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<result>
<xsl:for-each-group select="root/item" group-by="(position() - 1) idiv 3">
<row>
<xsl:for-each select="current-group()">
<cell><xsl:value-of select="."/></cell>
</xsl:for-each>
</row>
</xsl:for-each-group>
</result>
</xsl:template>
</xsl:stylesheet>
将 items 分组为 rows,每个 3 cells,产生
<result>
<row>
<cell>1</cell>
<cell>2</cell>
<cell>3</cell>
</row>
<row>
<cell>4</cell>
<cell>5</cell>
<cell>6</cell>
</row>
<row>
<cell>7</cell>
</row>
</result>
因此只有 item 个元素被计算在分配位置中。
现在,如果我将 for-each-group 更改为使用 group-starting-with="*[position() mod 3 = 1]"
。我在第一行得到项目 1、2 和 3;第二行第 4 项和第 5 项;第三行中的第 6 项和第 7 项(因此 notanitem 元素被计算在分配位置中)。
似乎在第一种情况下,位置函数只对项目进行评估,而在第二种情况下,位置函数是在整个文档(或根元素下的子元素)上进行评估。
是这样吗? group-by
评估仅限于 仅 到由 for-each-group 构造实际选择的项目,但 group-starting-with
评估基于整个子树这些元素在(包括未选择的元素)?评估这两个属性的上下文是什么?
我觉得我对这些工作原理几乎有了正确的想法,但这让我感到困惑,因为我不太清楚在规范中解释这个的正确方法,以及我看过的其他问题'似乎在询问或回答这个问题。
group-by
是一个计算分组键的表达式,但是 group-starting-with
是一个模式(您从 XSLT 1.0 知道 match
属性 xsl:template
或xsl:key
).
如果您改用 group-starting-with="item[position() mod 3 = 1]"
,那么您会看到与 group-by
.
至于group-by
的评价,见https://www.w3.org/TR/xslt20/#grouping里面说的
When calculating grouping keys for an item in the population, the expression contained in the group-by or group-adjacent attribute is evaluated with that item as the context item, with its position in population order as the context position, and with the size of the population as the context size. The resulting sequence is atomized, and each atomic value in the atomized sequence acts as a grouping key for that item in the population.
population
https://www.w3.org/TR/xslt20/#dt-population定义为for-each-group select="expression"
选择的序列:
[Definition: The sequence of items to be grouped, which is referred to as the population, is determined by evaluating the XPath expression contained in the select attribute.]
至于在 group-starting-with
的模式中调用 position()
,您首先需要查看模式,显然 *
匹配所有元素,而不仅仅是 item
元素。