我正在考虑与此处涉及的问题类似的问题
Transforming List into a 2-D Table
但有轻微的皱纹。我的XML没有任何特定的顺序,我想将它排序显示。例如,我的XML是
<items>
<item>A</item>
<item>C</item>
<item>E</item>
<item>B</item>
<item>D</item>
<!-- ... any number of item nodes ... -->
<item>
我希望我的输出是(为了说明目的,我忽略了非命名节点)
<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):
<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) < $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>
我尝试在各种apply-templates中插入命令,但这不起作用。
想法?
杰夫
从评论中更新
我想输出一个多语言表 条目有3列 按字母顺序垂直
答案 0 :(得分:1)
更新:现在,解释了新的requeriment,这个样式表:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:strip-space elements="*"/>
<xsl:param name="pColumns" select="3"/>
<xsl:template match="items">
<xsl:variable name="vrtfChilds">
<xsl:for-each select="*">
<xsl:sort/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vChilds" select="msxsl:node-set($vrtfChilds)/*"/>
<xsl:variable name="vRows"
select="ceiling(count($vChilds) div $pColumns)"/>
<table>
<xsl:for-each select="$vChilds[$vRows >= position()]">
<tr>
<xsl:call-template name="columns">
<xsl:with-param name="pRows" select="$vRows"/>
</xsl:call-template>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="columns">
<xsl:param name="pData" select="."/>
<xsl:param name="pColumn" select="$pColumns"/>
<xsl:param name="pRows" select="0"/>
<xsl:if test="$pColumn">
<td>
<xsl:apply-templates select="$pData"/>
</td>
<xsl:call-template name="columns">
<xsl:with-param name="pData"
select="$pData/following-sibling::*[$pRows]"/>
<xsl:with-param name="pColumn" select="$pColumn - 1"/>
<xsl:with-param name="pRows" select="$pRows"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<table>
<tr>
<td>A</td>
<td>C</td>
<td>E</td>
</tr>
<tr>
<td>B</td>
<td>D</td>
<td></td>
</tr>
</table>
注意:node-set
扩展功能,用于两阶段转换。
答案 1 :(得分:1)
此转化:
<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>