XSL:将 xml 转换为已排序的多列 html 表

问题描述:

我正在研究与此处涵盖的内容类似的问题

I am looking at a similar problem to what was covered here

将列表转换为二维表

但有轻微的皱纹.我的 XML 没有任何特定的顺序,我想对其进行排序以进行显示.例如我的 XML 是

but with a slight wrinkle. My XML is not in any particular order and I would like to sort it for display. For example my XML is

<items>  
  <item>A</item>  
  <item>C</item>  
  <item>E</item>  
  <item>B</item>  
  <item>D</item> 
  <!-- ... any number of item nodes ... -->
<item>  

并且我希望我的输出是(出于说明目的,我忽略了未命名的节点)

and I want my output to be (where I am ignoring the non-named nodes for illustrative purposes)

<table>
    <tr>
        <td>A</td>
        <td>C</td>
        <td>E</td>
    </tr>
    <tr>
        <td>B</td>
        <td>D</td>
        <td />
    </tr>
</table>

我基于此的 XSL 来自上面的链接(我需要使用 XSL 1.0):

The XSL I am basing this off is from the above link (I need to use XSL 1.0):

<xsl:template match="/*">
    <table>
        <xsl:call-template name="make-columns">
            <xsl:with-param name="nodelist" select="item"/>
        </xsl:call-template>
    </table>
</xsl:template>

<xsl:template name="make-columns">
    <xsl:param name="nodelist"/>
    <xsl:param name="columns-number" select="3"/>

    <tr>
        <xsl:apply-templates select="$nodelist[
                        not(position() > $columns-number)
                        ]"/>
        <xsl:if test="count($nodelist) &lt; $columns-number">
            <xsl:call-template name="empty-cells">
                <xsl:with-param name="finish" 
                                select="$columns-number - count($nodelist)"/>
            </xsl:call-template>
        </xsl:if>
    </tr>

    <!-- If some nodes are left, recursively call current
    template, passing only nodes that are left -->
    <xsl:if test="count($nodelist) > $columns-number">
        <xsl:call-template name="make-columns">
            <xsl:with-param name="nodelist" select="$nodelist[
                                    position() > $columns-number
                                    ]"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template match="item">
    <td>
        <xsl:apply-templates/>
    </td>
</xsl:template>

<xsl:template name="empty-cells">
    <xsl:param name="finish"/>
    <td/>
    <xsl:if test="not($finish = 1)">
        <xsl:call-template name="empty-cells">
            <xsl:with-param name="finish" select="$finish - 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

我曾尝试在各种应用模板中插入命令,但不起作用.

I have tried inserting commands within the various apply-templates but that doesn't work.

想法?

杰夫

评论更新

我想输出一个多列表有 3 列,其中条目是按字母顺序垂直

I want to output a multicolum table with 3 columns where the entries are in alphabetical order vertically

这种转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common"
  exclude-result-prefixes="ext">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pNumCols" select="3"/>

 <xsl:variable name="vNumRows" select=
      "ceiling(count(/*/*) div $pNumCols)"/>

 <xsl:variable name="vrtfSorted">
   <xsl:for-each select="/*/*">
    <xsl:sort/>
    <xsl:copy-of select="."/>
   </xsl:for-each>
 </xsl:variable>

 <xsl:variable name="vSorted"
      select="ext:node-set($vrtfSorted)/*"/>

 <xsl:template match="/">
  <table>
   <xsl:apply-templates select=
     "$vSorted[not(position() > $vNumRows)]"/>
  </table>
 </xsl:template>

 <xsl:template match="item">
  <tr>
   <xsl:apply-templates select=
   "(.|following-sibling::*[position() mod $vNumRows =0])/text()"/>
  </tr>
 </xsl:template>

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

应用于提供的 XML 文档时:

<items>
    <item>A</item>
    <item>C</item>
    <item>E</item>
    <item>B</item>
    <item>D</item>
</items>

产生想要的、正确的结果:

<table>
  <tr>
    <td>A</td>
    <td>C</td>
    <td>E</td>
  </tr>
  <tr>
    <td>B</td>
    <td>D</td>
  </tr>
</table>