Xml XSLT将每n个项目包装到一个新容器中

Xml XSLT将每n个项目包装到一个新容器中,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,所以我以前写过基本的XSLT,但遇到了一个新问题 我们正在使用一个网格系统,因此,对每个使用一个简单的是不够的。相反,我需要在HTML输出中每隔3项创建一个新的行 简而言之,我需要帮助(从头开始)编写XSLT,以便: 这个想法: <!-- The below div ("group") should repeat every group --> <div class="group"> <h2>Group #</h2> <!-- The

所以我以前写过基本的XSLT,但遇到了一个新问题

我们正在使用一个网格系统,因此,对每个使用一个简单的
是不够的。相反,我需要在HTML输出中每隔3项创建一个新的

简而言之,我需要帮助(从头开始)编写XSLT,以便:

这个想法:

<!-- The below div ("group") should repeat every group -->
<div class="group">
  <h2>Group #</h2>
  <!-- The below div ("row") should repeat every 3 items -->
  <div class="row">
    <!-- The below div ("four columns") should be repeated every item -->
    <div class="four columns">
      <div class="item">...</div>
    </div>
  </div>
</div>

团体#
...
XML:

<group name="Group 1">
  <item name="Item 1" />
  <item name="Item 2" />
  <item name="Item 3" />
  <item name="Item 4" />
</group>

<group name="Group 2">
  ...
</group>

...
它应该是什么样子的输出:

<div class="group">
  <h2>Group 1</h2>
  <div class="row">
    <div class="four columns">
      <div class="item">Item 1</div>
    </div>
    <div class="four columns">
      <div class="item">Item 2</div>
    </div>
    <div class="four columns">
      <div class="item">Item 3</div>
    </div>
  </div>

  <div class="row">  
    <div class="four columns">
      <div class="item">Item 4</div>
    </div>
  </div>
</div>

<div class="group">
  <h2>Group 2</h2>
  ...
</div>

第一组
项目1
项目2
项目3
项目4
第2组
...

假设您有一个要分组的行数的参数,您可以从选择当前元素的项开始,该元素位于第1、第4、第7等位置

<xsl:apply-templates select="item[position() mod $rows = 1]" mode="group"/>

(注意模式的使用,因为您将有两个模板匹配元素)

然后,在与此匹配的模板中,您可以像这样选择组中的所有项目

<xsl:apply-templates select="self::*|following-sibling::item[position() &lt; $rows]"/>

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:param name="rows" select="3"/>

   <xsl:template match="group">
      <div class="group">
         <h2><xsl:value-of select="@name"/></h2>
         <xsl:apply-templates select="item[position() mod $rows = 1]" mode="group"/>
      </div>
   </xsl:template>

   <xsl:template match="item" mode="group">
      <div class="row">
         <xsl:apply-templates select="self::*|following-sibling::item[position() &lt; $rows]"/>
      </div>
   </xsl:template>

   <xsl:template match="item">
      <div class="four columns">
         <div class="item"><xsl:value-of select="@name"/></div>
      </div>
   </xsl:template>
</xsl:stylesheet>

当应用于以下XML时

<groups>
    <group name="Group 1">
        <item name="Item 1"/>
        <item name="Item 2"/>
        <item name="Item 3"/>
        <item name="Item 4"/>
    </group>
    <group name="Group 2">
        <item name="Item 1"/>
        <item name="Item 2"/>
        <item name="Item 3"/>
        <item name="Item 4"/>
    </group>
</groups>

以下是输出

<a>
   <div class="group">
      <h2>Group 1</h2>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 1</div>
         </div>
         <div class="four columns">
            <div class="item">Item 2</div>
         </div>
         <div class="four columns">
            <div class="item">Item 3</div>
         </div>
      </div>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 4</div>
         </div>
      </div>
   </div>
   <div class="group">
      <h2>Group 2</h2>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 1</div>
         </div>
         <div class="four columns">
            <div class="item">Item 2</div>
         </div>
         <div class="four columns">
            <div class="item">Item 3</div>
         </div>
      </div>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 4</div>
         </div>
      </div>
   </div>
</a>

第一组
项目1
项目2
项目3
项目4
第2组
项目1
项目2
项目3
项目4
编辑:在回答您的评论时,如果您想更改最后一列的类名(如果没有确切的列数),可以使用xsl:choose来检查它是否是最后一项,并且它的位置与所需的数字不匹配

<xsl:template match="item">
   <div>
      <xsl:attribute name="class">
         <xsl:choose>
            <xsl:when test="not(following-sibling::item) and position() mod $rows != 0">end</xsl:when>
            <xsl:otherwise>four columns</xsl:otherwise>
         </xsl:choose>
      </xsl:attribute>
      <div class="item">
         <xsl:value-of select="@name"/>
      </div>
   </div>
</xsl:template>

结束
四列

假设您有一个要分组的行数的参数,您可以从选择当前元素的项开始,该元素位于第1、第4、第7等位置

<xsl:apply-templates select="item[position() mod $rows = 1]" mode="group"/>

(注意模式的使用,因为您将有两个模板匹配元素)

然后,在与此匹配的模板中,您可以像这样选择组中的所有项目

<xsl:apply-templates select="self::*|following-sibling::item[position() &lt; $rows]"/>

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:param name="rows" select="3"/>

   <xsl:template match="group">
      <div class="group">
         <h2><xsl:value-of select="@name"/></h2>
         <xsl:apply-templates select="item[position() mod $rows = 1]" mode="group"/>
      </div>
   </xsl:template>

   <xsl:template match="item" mode="group">
      <div class="row">
         <xsl:apply-templates select="self::*|following-sibling::item[position() &lt; $rows]"/>
      </div>
   </xsl:template>

   <xsl:template match="item">
      <div class="four columns">
         <div class="item"><xsl:value-of select="@name"/></div>
      </div>
   </xsl:template>
</xsl:stylesheet>

当应用于以下XML时

<groups>
    <group name="Group 1">
        <item name="Item 1"/>
        <item name="Item 2"/>
        <item name="Item 3"/>
        <item name="Item 4"/>
    </group>
    <group name="Group 2">
        <item name="Item 1"/>
        <item name="Item 2"/>
        <item name="Item 3"/>
        <item name="Item 4"/>
    </group>
</groups>

以下是输出

<a>
   <div class="group">
      <h2>Group 1</h2>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 1</div>
         </div>
         <div class="four columns">
            <div class="item">Item 2</div>
         </div>
         <div class="four columns">
            <div class="item">Item 3</div>
         </div>
      </div>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 4</div>
         </div>
      </div>
   </div>
   <div class="group">
      <h2>Group 2</h2>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 1</div>
         </div>
         <div class="four columns">
            <div class="item">Item 2</div>
         </div>
         <div class="four columns">
            <div class="item">Item 3</div>
         </div>
      </div>
      <div class="row">
         <div class="four columns">
            <div class="item">Item 4</div>
         </div>
      </div>
   </div>
</a>

第一组
项目1
项目2
项目3
项目4
第2组
项目1
项目2
项目3
项目4
编辑:在回答您的评论时,如果您想更改最后一列的类名(如果没有确切的列数),可以使用xsl:choose来检查它是否是最后一项,并且它的位置与所需的数字不匹配

<xsl:template match="item">
   <div>
      <xsl:attribute name="class">
         <xsl:choose>
            <xsl:when test="not(following-sibling::item) and position() mod $rows != 0">end</xsl:when>
            <xsl:otherwise>four columns</xsl:otherwise>
         </xsl:choose>
      </xsl:attribute>
      <div class="item">
         <xsl:value-of select="@name"/>
      </div>
   </div>
</xsl:template>

结束
四列

您没有编写问题所在。向我们展示你的代码(一些XSLT)你正在尝试做什么。谢谢@TOUDIdel,我在介绍中做了更多的澄清。我希望我的问题现在清楚了。你没有写什么问题。向我们展示你的代码(一些XSLT)你正在尝试做什么。谢谢@TOUDIdel,我在介绍中做了更多的澄清。我希望我的问题现在清楚了。绝对令人惊讶!你回答得太好了!:)我还有最后一个问题,不是原来问题的一部分。在我的示例中,每行必须总共有12列。如果一行加起来不超过12列,那么最后一列必须应用类
end
(因此在上面的示例中,第4项的父div将有
end
类)。关于如何添加该功能,有什么想法吗?我的问题中添加了一点,希望能解释一下。希望有帮助!只需重新调整语法到我的数据源,它在不到五分钟的时间内工作!谢谢太棒了!你回答得太好了!:)我还有最后一个问题,不是原来问题的一部分。在我的示例中,每行必须总共有12列。如果一行加起来不超过12列,那么最后一列必须应用类
end
(因此在上面的示例中,第4项的父div将有
end
类)。关于如何添加该功能,有什么想法吗?我的问题中添加了一点,希望能解释一下。希望有帮助!只需重新调整语法到我的数据源,它在不到五分钟的时间内工作!谢谢