所以我过去曾写过基本的XSLT,但我遇到了一个新问题。
我们正在使用网格系统,因此,简单的for-each
是不够的。相反,我需要每3个项目在HTML输出中创建一个新的row
。
简而言之,我需要帮助编写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>
答案 0 :(得分:5)
假设您有一个参数来表示您希望分组的行数,您可以先选择 item 元素和当前 group 元素。第1,第4,第7等位置。
<xsl:apply-templates select="item[position() mod $rows = 1]" mode="group"/>
(注意使用模式,因为您将有两个匹配项元素的模板)
然后,在与之匹配的模板中,您将选择组中的所有项目,如此
<xsl:apply-templates select="self::*|following-sibling::item[position() < $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() < $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>