0

当前列表

当前列表

Access     Autocad     Burger 

Layout     Photoshop   Sandwich

VisualStudio 

我使用了盒装视图并编辑了如下所示的源以获得三列

<xsl:when test="$Position mod 3 = 0">

但是所需物品的顺序是这样的

 Access       Layout       VisualStudio 
 Autocad      Photoshop 
 Burger       Sandwich

有人可以建议一种方法来实现这一目标吗?

这是 xml 的一部分

<xsl:template name="NewTRJumbo" ddwrt:ghost="">
    <xsl:param name="Position" select="1"/>
    <xsl:param name="Collapse" select="."/>
    <xsl:choose>
        <xsl:when test="$Position mod 3 = 0">
            <xsl:text disable-output-escaping="yes">&lt;/tr&gt;</xsl:text>
            <xsl:call-template name="NewTR">
                <xsl:with-param name="Collapse" select="$Collapse"/>
                <xsl:with-param name="EmptyLine" select="1"/>
            </xsl:call-template>
            <xsl:text disable-output-escaping="yes">&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;</xsl:text>
            <xsl:call-template name="NewTR">
                <xsl:with-param name="Collapse" select="$Collapse"/>
            </xsl:call-template>
  </xsl:when>
        <xsl:otherwise>
    <td width="1.5%">

    </td>
  </xsl:otherwise>
    </xsl:choose>

4

1 回答 1

0

我假设你有一个元素的 XML 文档,例如,像这样

<items>
   <item>Access</item>
   <item>Autocad</item>
   <item>Burger</item>
   <item>Layout</item>
   <item>Photoshop</item>
   <item>Sandwich</item>
   <item>VisualStudio</item>
</items>

并且您希望将它们分组为 3 列,但项目首先从上到下运行,而不是从左到右。您当前的测试$Position mod 3 = 0部分沿着正确的路线进行,但实际上您在这里每行开始一个新行,因此最终从左到右。

需要提及的一件事是您对这行代码的使用

<xsl:text disable-output-escaping="yes">&lt;/tr&gt;</xsl:text>

看起来您只是在遍历元素,并尝试在每三个元素之后输出一个结束tr标记。XSLT 是一种函数式语言,因此您需要以不同的思维方式进行处理,并以与普通程序语言不同的方式做事。

首先,您需要找到要输出的行数

<xsl:param name="columns" select="3"/>
<xsl:variable name="items" select="count(/*/item)"/>
<xsl:variable name="rows" select="ceiling($items div $columns)"/>

即行数是项目总数除以列数。

然后,您需要选择每行的第一项,这很简单,因为这些将是列表中的前“n”项(注意使用模式,因为最终的 XSLT 将有两个模板匹配元素)

 <xsl:apply-templates select="item[position() &lt;= $rows]" mode="row"/>

在匹配起始项目的模板中,您需要输出当前项目,以及该行中的以下兄弟项目

 <xsl:apply-templates select=".|following-sibling::item[position() mod $rows = 0]"/>

唯一要考虑的另一件事是在某些行的末尾添加一个空白单元格。这可以通过计算剩余项目与总项目的数量来完成

 <xsl:variable name="lastItem" select="(position() + $rows * ($columns - 1) - $items)" />
 <xsl:if test="$lastItem > 0">
     <td colspan="{ceiling($lastItem div $rows)}"></td>
 </xsl:if>

尝试以下 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="columns" select="3"/>
    <xsl:variable name="items" select="count(/*/item)"/>
    <xsl:variable name="rows" select="ceiling($items div $columns)"/>

    <xsl:template match="/*">
        <table>
            <xsl:apply-templates select="item[position() &lt;= $rows]" mode="row"/>
        </table>
    </xsl:template>

    <xsl:template match="item" mode="row">
        <tr>
            <xsl:apply-templates select=".|following-sibling::item[position() mod $rows = 0]"/>
            <xsl:variable name="lastItem" select="(position() + $rows * ($columns - 1) - $items)" />
             <xsl:if test="$lastItem > 0">
                 <td colspan="{ceiling($lastItem div $rows)}"></td>
             </xsl:if>
        </tr>
    </xsl:template>

    <xsl:template match="item">
        <td>
            <xsl:value-of select="."/>
        </td>
    </xsl:template>
</xsl:stylesheet>

当应用于问题开头显示的 XML 时,输出如下

<table>
   <tr>
       <td>Access</td>
       <td>Layout</td>
       <td>VisualStudio</td>
   </tr>
   <tr>
       <td>Autocad</td>
       <td>Photoshop</td>
       <td colspan="1"></td>
   </tr>
   <tr>
       <td>Burger</td>
       <td>Sandwich</td>
       <td colspan="1"></td>
   </tr>
</table>
于 2013-01-30T07:39:46.597 回答