Вы говорите, что хотите обрабатывать свои элементы в группах по n. Следующий XSLT 1.0 решение делает это:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:param name="pGroupCount" select="3" />
<xsl:template match="/lvl-0">
<xsl:copy>
<!-- select the nodes that start a group -->
<xsl:apply-templates mode="group" select="
lvl-1/lvl-2[position() mod $pGroupCount = 1]
" />
</xsl:copy>
</xsl:template>
<xsl:template match="lvl-2" mode="group">
<!-- select the nodes belong to the current group -->
<xsl:variable name="current-group" select="
. | following-sibling::lvl-2[position() < $pGroupCount]
" />
<!-- output the current group, you can also do calculations with it -->
<group id="{position()}">
<xsl:copy-of select="$current-group" />
</group>
</xsl:template>
</xsl:stylesheet>
При применении этого входного документа:
<lvl-0>
<lvl-1>
<lvl-2>item.0</lvl-2>
<lvl-2>item.1</lvl-2>
<lvl-2>item.2</lvl-2>
<lvl-2>item.3</lvl-2>
<lvl-2>item.4</lvl-2>
<lvl-2>item.5</lvl-2>
<a>foo</a><!-- to prove that position() calculations still work -->
<lvl-2>item.6</lvl-2>
<lvl-2>item.7</lvl-2>
<lvl-2>item.8</lvl-2>
<lvl-2>item.9</lvl-2>
</lvl-1>
</lvl-0>
Следующий вывод генерируется:
<lvl-0>
<group id="1">
<lvl-2>item.0</lvl-2>
<lvl-2>item.1</lvl-2>
<lvl-2>item.2</lvl-2>
</group>
<group id="2">
<lvl-2>item.3</lvl-2>
<lvl-2>item.4</lvl-2>
<lvl-2>item.5</lvl-2>
</group>
<group id="3">
<lvl-2>item.6</lvl-2>
<lvl-2>item.7</lvl-2>
<lvl-2>item.8</lvl-2>
</group>
<group id="4">
<lvl-2>item.9</lvl-2>
</group>
</lvl-0>
Чтобы понять это, вы должны знать, как position()
работает. При использовании, как это:
lvl-1/lvl-2[position() mod $pGroupCount = 1]
это относится к положению lvl-2
узлов в пределах их родителя (!). В этом случае, есть только один из родителей, поэтому item.0
имеет позицию 1 и item.9
имеет позицию 10.
При использовании, как это:
following-sibling::lvl-2[position() < $pGroupCount]
это относится к относительному положению вдоль оси following-sibling::
. В этом контексте item.1
будет иметь относительное положение 1 в отношении item.0
. (В принципе, это то же самое, что и выше, который только подсчитывает вдоль (неявной) child::
оси.)
При использовании самостоятельно, как здесь:
<group id="{position()}">
это относится к позиции из текущий узел в пакете, который обрабатывается в данный момент.В нашем случае «партия» состоит из узлов, которые начинают группу (item.0
, item.3
, item.6
, item.9
), поэтому она идет от 1 до 4.
Извинения - слепо дал тот же ответ, как и ты, не обращая внимания. –