XSLT包装新容器中的每个项目

Nes*_*Dan 1 xml xslt xslt-1.0

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

我们正在使用网格系统,因此,简单的for-each做法是不够的.相反,我需要row每3个项目在我的HTML输出中创建一个新的.

简而言之,我需要帮助编写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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

看起来应该是什么输出:

<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>
Run Code Online (Sandbox Code Playgroud)

Tim*_*m C 5

假设您有一个参数用于您希望分组的行数,您可以从选择具有当前元素的元素开始,这些元素位于第1,第4,第7等位置.

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

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

然后,在与此匹配的模板中,您将选择组中的所有项目,如此

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

这是完整的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>
Run Code Online (Sandbox Code Playgroud)

应用于以下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>
Run Code Online (Sandbox Code Playgroud)

输出如下

<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>
Run Code Online (Sandbox Code Playgroud)

编辑:在回答您的评论时,如果您想要更改最后一列的类名,如果没有确切的列数,您可以使用xsl执行此操作:选择检查它是否是最后一项,并且它是位置与所需数量不符.

<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>
Run Code Online (Sandbox Code Playgroud)