Предполагая, что вы определяете параметр с именем blocks , первый элемент в каждом блоке будет сопоставляться простым выполнением следующего:
<xsl:apply-templates select="product/*[position() <= $blocks]" />
В шаблоне, который соответствует такому элементуЗатем вам нужно выбрать сам элемент, а затем все последующие элементы для блока (который будет зависеть от количества блоков), например, так:
<xsl:apply-templates
select="self::*|following-sibling::*[position() mod $blocks = 0]"
mode="block" />
Обратите внимание на режим здесь дляостановить рекурсивный вызов шаблона.В соответствующем шаблоне вы можете добавить свой код для тегов span в вашем случае.
Итак, с учетом следующего XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:param name="blocks" select="4" />
<xsl:template match="/">
<xsl:apply-templates select="product/*[position() <= $blocks]" />
</xsl:template>
<xsl:template match="product/*">
<div>
<xsl:apply-templates
select="self::*|following-sibling::*[position() mod $blocks = 0]"
mode="block" />
</div>
</xsl:template>
<xsl:template match="*" mode="block">
<span><xsl:value-of select="." /></span>
</xsl:template>
</xsl:stylesheet>
Применительно кВ вашем примере XML выводится следующее:
<div><span>1</span><span>5</span></div>
<div><span>2</span><span>6</span></div>
<div><span>3</span><span>7</span></div>
<div><span>4</span><span>8</span></div>
Измените параметр на 3, и выведите следующее
<div><span>1</span><span>4</span><span>7</span></div>
<div><span>2</span><span>5</span><span>8</span></div>
<div><span>3</span><span>6</span></div>