更改列表顺序

时间:2013-01-29 05:27:44

标签: xslt sharepoint-2010 sharepoint-designer

当前列表

CurrentList

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>

1 个答案:

答案 0 :(得分: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'项(请注意使用模式,因为final XSLT将有两个与 item 元素匹配的模板

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