【问题标题】:XSLT to transform list into table with columns determined dynamicallyXSLT 将列表转换为具有动态确定列的表
【发布时间】:2009-10-27 23:23:14
【问题描述】:

我需要这个 XML,

<list columns="3">
  <item>martin</item>
  <item>donald</item>
  <item>whistler</item>
  <item>mother</item>
  <item>carl</item>
  <item>liz</item>
  <item>cosmo</item>
</list>

看起来像这样:

<table>
  <tr>
    <td>martin</td>
    <td>donald</td>
    <td>whistler</td>
  </tr>
  <tr>
    <td>mother</td>
    <td>carl</td>
    <td>liz</td>
  </tr>
  <tr>
    <td>cosmo</td>
    <td></td>
    <td></td>
  </tr>
</table>

columns="4" 时应该是这样的:

<table>
  <tr>
    <td>martin</td>
    <td>donald</td>
    <td>whistler</td>
    <td>mother</td>
  </tr>
  <tr>
    <td>carl</td>
    <td>liz</td>
    <td>cosmo</td>
    <td></td>
  </tr>
</table>

关于 XSLT 文件应该是什么样子的任何提示?据我所知,它需要某种循环(递归?),但我不确定是否有更优雅的方式。

【问题讨论】:

    标签: xml xslt multiple-columns


    【解决方案1】:

    我会采用的方法是通过在每个项目上使用 position() 的“mod”函数来匹配第 1、第 4、第 7 个位置的项目。

    匹配每个这样的项目后,只需根据列数循环遍历以下同级。

    对于最后一行,可能没有足够的项目来完成该行,有一个递归模板可以根据最后一行中的项目数量添加到空单元格中。

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
       <!-- Global variable to get column count -->
       <xsl:variable name="columns" select="number(/list/@columns)"/>
    
       <!-- Match the root node -->
       <xsl:template match="list">
          <table>
             <!-- Match items in the 1st, 4th, 7th positions, etc (or whatever the column variable holds) -->
             <xsl:apply-templates select="item[position() mod $columns = 1]"/>
          </table>
       </xsl:template>
    
       <xsl:template match="item">
          <tr>
             <!-- Output the current item -->
             <td>
                <xsl:value-of select="."/>
             </td>
             <!-- Output the following items based on the number of required columns -->
             <xsl:for-each select="following-sibling::item[position() &lt; $columns]">
                <td>
                   <xsl:value-of select="."/>
                </td>
             </xsl:for-each>
             <!-- Add in any empty cells if numberof following items is not sufficient -->
             <xsl:call-template name="emptycell">
                <xsl:with-param name="cellcounter" select="count(following-sibling::item[position() &lt; $columns]) + 1" />
             </xsl:call-template>
          </tr>
       </xsl:template>
    
       <!-- Recursive template to add in empty cells when there are not enough items to complete a row -->
       <xsl:template name="emptycell">
          <xsl:param name="cellcounter" />
          <xsl:if test="$cellcounter &lt; $columns">
             <td></td>
             <xsl:call-template name="emptycell">
                <xsl:with-param name="cellcounter" select="$cellcounter + 1" />
             </xsl:call-template>
          </xsl:if>   
       </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      【解决方案2】:

      一些有用的东西,但看起来有点难看:abuse position()。

      <xsl:param name="columns">4</xsl:param>
      <xsl:template match="list">
        <xsl:variable name="theList" select="."/>
        <xsl:for-each select="//*[position()<(count(item) / $columns)]>
          <xsl:variable name="idx" select="position()"/>
          <tr>
          <xsl:for-each select="//*[position()<$columns]">
             <td><xsl:value-of select="$theList/item[position() + $idx * $columns]"/></td>
          </xsl:for-each>
          </tr>
        </xsl:for-each>
      </xsl:template>
      

      还有其他方法:例如,首先选择列表中除以其余 0 列的所有节点,然后遍历这些节点。

      有关上述技术的详细说明,请参阅http://www.ibm.com/developerworks/library/x-tipnodst.html

      【讨论】:

        【解决方案3】:

        我建议使用CSS3 columns。该规范将很快成为候选推荐(要求实施阶段),并且已经在 Gecko 和 WebKit(Firefox、Safari、Chrome)中实施,带有供应商前缀。

        代码:

        ul { -moz-column-count: 3; -webkit-column-count: 3; }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-19
          • 1970-01-01
          相关资源
          最近更新 更多