Xslt 将面向列的数据转换为面向行的HTML
我的源XML逐列提供数据;这些细胞有不同的高度。使用XSLT1.0,我需要围绕这一点来匹配HTML的逐行表格式 示例:我需要像这样转换输入数据Xslt 将面向列的数据转换为面向行的HTML,xslt,Xslt,我的源XML逐列提供数据;这些细胞有不同的高度。使用XSLT1.0,我需要围绕这一点来匹配HTML的逐行表格式 示例:我需要像这样转换输入数据 <source> <column> <cell height="1">col A row 1</cell> <cell height="2">col A rows 2-3</cell> </column> <
<source>
<column>
<cell height="1">col A row 1</cell>
<cell height="2">col A rows 2-3</cell>
</column>
<column>
<cell height="1">col B row 1</cell>
<cell height="1">col B row 2</cell>
<cell height="1">col B row 3</cell>
</column>
<column>
<cell height="3">col C rows 1-3</cell>
</column>
</source>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="1">col B row 1</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
<td rowspan="1">col B row 2</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="2">col B row 1-2</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
第1列
A列第2-3行
B列第1行
B列第2排
B列第3排
第C列第1-3行
像这样的HTML表
<source>
<column>
<cell height="1">col A row 1</cell>
<cell height="2">col A rows 2-3</cell>
</column>
<column>
<cell height="1">col B row 1</cell>
<cell height="1">col B row 2</cell>
<cell height="1">col B row 3</cell>
</column>
<column>
<cell height="3">col C rows 1-3</cell>
</column>
</source>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="1">col B row 1</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
<td rowspan="1">col B row 2</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="2">col B row 1-2</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
第1列
B列第1行
第C列第1-3行
A列第2-3行
B列第2排
B列第3排
怎么做
编辑:这里是另一个示例,其中没有任何一列的单元格数与表行数相同
<source>
<column id="A">
<cell height="1">col A row 1</cell>
<cell height="2">col A rows 2-3</cell>
</column>
<column id="B">
<cell height="2">col B row 1-2</cell>
<cell height="1">col B row 3</cell>
</column>
<column id="C">
<cell height="3">col C rows 1-3</cell>
</column>
</source>
第1列
A列第2-3行
B列第1-2行
B列第3排
第C列第1-3行
像这样的HTML表
<source>
<column>
<cell height="1">col A row 1</cell>
<cell height="2">col A rows 2-3</cell>
</column>
<column>
<cell height="1">col B row 1</cell>
<cell height="1">col B row 2</cell>
<cell height="1">col B row 3</cell>
</column>
<column>
<cell height="3">col C rows 1-3</cell>
</column>
</source>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="1">col B row 1</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
<td rowspan="1">col B row 2</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="2">col B row 1-2</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
第1列
B列第1-2行
第C列第1-3行
A列第2-3行
B列第3排
I.XSLT 1.0解决方案
此转换:
<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:strip-space elements="*"/>
<xsl:variable name="vrtfPass1">
<xsl:apply-templates mode="pass1"/>
</xsl:variable>
<xsl:variable name="vPass1"
select="ext:node-set($vrtfPass1)"/>
<xsl:variable name="vMaxRow">
<xsl:for-each select=
"$vPass1/*/*/cell/@startRow">
<xsl:sort select="." data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="node()|@*" mode="pass1">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="cell" mode="pass1">
<cell height="{@height}"
startRow="{sum(preceding-sibling::*/@height) +1}">
<xsl:copy-of select="text()"/>
</cell>
</xsl:template>
<xsl:template match="/">
<table>
<xsl:call-template name="makeRows">
<xsl:with-param name="pmaxRow" select="$vMaxRow"/>
</xsl:call-template>
</table>
</xsl:template>
<xsl:template name="makeRows">
<xsl:param name="prowNum" select="1"/>
<xsl:param name="pmaxRow" select="1"/>
<xsl:if test="not($prowNum > $pmaxRow)">
<tr>
<xsl:apply-templates select=
"$vPass1/*/*/cell[@startRow = $prowNum]"/>
</tr>
<xsl:call-template name="makeRows">
<xsl:with-param name="prowNum" select="$prowNum+1"/>
<xsl:with-param name="pmaxRow" select="$pmaxRow"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="cell">
<td rowspan="{@height}"><xsl:value-of select="."/></td>
</xsl:template>
</xsl:stylesheet>
<source>
<column>
<cell height="1">col A row 1</cell>
<cell height="2">col A rows 2-3</cell>
</column>
<column>
<cell height="2">col B row 1-2</cell>
<cell height="1">col B row 3</cell>
</column>
<column>
<cell height="3">col C rows 1-3</cell>
</column>
</source>
<table>
<tr>
<td rowspan="1">col A row 1</td>
<td rowspan="2">col B row 1-2</td>
<td rowspan="3">col C rows 1-3</td>
</tr>
<tr>
<td rowspan="2">col A rows 2-3</td>
</tr>
<tr>
<td rowspan="1">col B row 3</td>
</tr>
</table>
迪米特里,你花了3分钟才想到这个。一个小时后,我仍在试着看看这一切是如何运作的@JPM:逻辑非常简单:
for$k in 1 to max(/*/column/count(cell)返回formatRow(/*/column/cell[$k])
——我们只是“切片”第k个单元格上的每一列,从而获得第k行。这是否取决于至少有一列具有高度为1的所有单元格?我不能依赖于此。我将添加另一个示例。在第二个示例中,我不知道
如何生成3个tr而不是2个tr。当然,您可以:exslt:node-set()
受除IE之外的所有浏览器的支持,因为IE在msxsl命名空间中使用msxsl:node-set()
:xmlns:msxsl=“urn:schemas microsoft com:xslt”
JPM:我认为您的编辑不够精确——无法决定将“col A rows 2-3”放在哪一行--在第1-2行或第2-3行。col A第2-3行
必须在第2-3行。col A第1行
已经在第1行了。JPM:我看不到任何逻辑--“col A第2-3行”
的高度为2,可以从第1行或第2行开始。是否使用单元格内容中的某些内容来确定将此单元格放在哪一行?XML的文档顺序决定了它。列A中的第一个单元格的高度为1。然后是另一个单元格;无论其高度如何,第二个单元格都必须从下一行开始。这就是第2行。如果列的第一个单元格的高度为8,则下一个单元格将从第9行开始。