代码之家  ›  专栏  ›  技术社区  ›  Marko

xslt-从foreach循环中获取最后一行(拆分为3列)

  •  1
  • Marko  · 技术社区  · 14 年前

    我在1-20之间循环 <li> 在使用XSLT的情况下,当以3列网格类型的格式显示时,我正在尝试解决如何将类添加到列表的最后一行。

    目前,我正在使用此代码添加 col-last 到列表中的每三列。

    <xsl:if test="not(position() mod 3)">
      <xsl:attribute name="class">col-last</xsl:attribute>
    </xsl:if>
    

    考虑到最后一行可能是1-3个项目,有没有方法可以将“最后一行”类添加到最后一行?

    例子

    4项

    <li>Item 1</li>
    <li>Item 2</li>
    <li class="col-last">Item 3</li>
    <li class="row-last">Item 4</li>
    

    5项

    <li>Item 1</li>
    <li>Item 2</li>
    <li class="col-last">Item 3</li>
    <li class="row-last">Item 4</li>
    <li class="row-last">Item 5</li>
    

    6项

    <li>Item 1</li>
    <li>Item 2</li>
    <li class="col-last">Item 3</li>
    <li class="row-last">Item 4</li>
    <li class="row-last">Item 5</li>
    <li class="row-last col-last">Item 6</li>
    

    感谢您的帮助。

    2 回复  |  直到 14 年前
        1
  •  2
  •   user357812    14 年前

    此样式表:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" omit-xml-declaration="yes"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="li">
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <xsl:variable name="class">
                    <xsl:if test="position() > last() - last() mod 3 - 3 * not(last() mod 3)">row-last </xsl:if>
                    <xsl:if test="not(position() mod 3)">col-last </xsl:if>
                </xsl:variable>
                <xsl:if test="$class != ''">
                    <xsl:attribute name="class">
                        <xsl:value-of select="normalize-space($class)"/>
                    </xsl:attribute>
                </xsl:if>
                <xsl:apply-templates select="node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    使用这些输入:

    <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    <li>Item 6</li>
    </ul>
    
    <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    <li>Item 5</li>
    </ul>
    
    <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
    </ul>
    

    结果:

    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li class="col-last">Item 3</li>
        <li class="row-last">Item 4</li>
        <li class="row-last">Item 5</li>
        <li class="row-last col-last">Item 6</li>
    </ul>
    
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li class="col-last">Item 3</li>
        <li class="row-last">Item 4</li>
        <li class="row-last">Item 5</li>
    </ul>
    
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li class="col-last">Item 3</li>
        <li class="row-last">Item 4</li>
    </ul>
    

    注: 当输出属性注意到具有相同名称的最后一个属性将覆盖以前的属性。

        2
  •  1
  •   Community Michael Schmitz    7 年前

    您可以使用另一个测试来查看 position() 在节点集大小的3以内,使用 last()-3 :

    此答案不能完全满足所述要求。 @Alejandro's answer 应该是公认的答案。