1

所以我过去写过基本的 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>

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>
4

1 回答 1

5

假设您有一个希望分组的行数的参数,您将从选择具有当前组元素的项目元素开始,这些元素位于第 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>

编辑:在回答您的评论时,如果您想在没有确切数量的列的情况下更改最后一列的类名,您可以使用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>
于 2013-03-28T21:28:18.000 回答