我有以下的XML。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<para align="center">BETWEEN</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="2">Column2 data</para>
<para columns="3">Column3 data</para>
<para align="center">AND</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="2">Column2 data</para>
<para columns="3">Column3 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para align="center">Between</para>
<para align="center">____________________</para>
</root>
这里实际上我想将para转换为表格列,因为我已经尝试过XSLT。但问题在于,每个段都会创建一个新表。
此处columns
属性指出数据属于哪一列,如果columns="1"
表示只有一行和一列。如果它是columns="2"
,则表明数据属于第二列中含有内容的同一行,如果前面有columns="1"
,那么同一行的第1列中应该有内容,否则列1应该留空。
我尝试的代码可以找到here
预期输出
<table>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td>Column 2 data</td>
<td>Column 3 data</td>
</tr>
</table>
<div class="para align-center">AND</div>
<table>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td>Column 2 data</td>
<td>Column 3 data</td>
</tr>
</table>
<table>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td>Column 2 data</td>
<td>Column 3 data</td>
</tr>
</table>
<table>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column 2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column 2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column 2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column 2 data</td>
<td></td>
</tr>
</table>
<div class="para align-center">BETWEEN</div>
请让我知道如何解决这个问题。
感谢。
答案 0 :(得分:1)
如果您真正使用XSLT 2.0(链接示例中的处理器是2.0处理器,但您的XSLT @version是1.0),您应该能够使用xsl:for-each-group
。您可以将para
元素分组到表中,然后将它们分组到这些表中的行中。
可能有更好的方法可以做到这一点,但我只有几分钟时间尝试一下。希望这足以让你开始。
XML输入(稍微修改以进行测试)
<root>
<para align="center">BETWEEN</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="2">Column2 data</para>
<para columns="3">Column3 data</para>
<para align="center">AND</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="1">Column1 data</para>
<para columns="2">Column2 data</para>
<para columns="3">Column3 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<para columns="2">Column2 data</para>
<!--Added for testing-->
<para columns="1">Column1 data</para>
<para columns="3">Column3 data</para>
<!--=================-->
<para align="center">Between</para>
<para align="center">____________________</para>
</root>
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output indent="yes" method="html"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="max-cols" select="max(/*/para/@columns)"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:for-each-group select="para" group-ending-with="para[@columns][@columns > following-sibling::para[@columns][1]/@columns]">
<xsl:apply-templates select="current-group()[not(@columns)][following-sibling::para[generate-id()=generate-id((current-group()[@columns])[1])]]"/>
<table>
<xsl:for-each-group select="current-group()[@columns]" group-starting-with="para[preceding-sibling::para[1]/@columns >= @columns]">
<tr>
<xsl:call-template name="empty-cols">
<xsl:with-param name="col-cnt" select="xs:integer(current-group()[position()=1]/@columns - 1)"/>
</xsl:call-template>
<xsl:apply-templates select="current-group()"/>
<xsl:call-template name="empty-cols">
<xsl:with-param name="col-cnt" select="xs:integer($max-cols - current-group()[last()]/@columns)"/>
</xsl:call-template>
</tr>
</xsl:for-each-group>
</table>
<xsl:apply-templates select="current-group()[not(@columns)][preceding-sibling::para[generate-id()=generate-id((current-group()[@columns])[last()])]]"/>
</xsl:for-each-group>
</xsl:template>
<xsl:template name="empty-cols">
<xsl:param name="col-cnt" as="xs:integer"/>
<xsl:for-each select="1 to $col-cnt">
<td/>
</xsl:for-each>
</xsl:template>
<xsl:template match="para[not(@columns)]">
<div class="para{if (string(@align)) then concat(' align-',@align) else ''}">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="para[@columns]">
<xsl:call-template name="empty-cols">
<xsl:with-param name="col-cnt" select="if (preceding-sibling::para[1][@columns][current()/@columns >= @columns - 1]) then xs:integer((@columns - 1) - preceding-sibling::para[1][@columns]/@columns) else xs:integer(0)"/>
</xsl:call-template>
<td>
<xsl:apply-templates/>
</td>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<div class="para align-center">BETWEEN</div>
<table>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td>Column2 data</td>
<td>Column3 data</td>
</tr>
</table>
<div class="para align-center">AND</div>
<table>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Column1 data</td>
<td>Column2 data</td>
<td>Column3 data</td>
</tr>
</table>
<table>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
<tr>
<td></td>
<td>Column2 data</td>
<td></td>
</tr>
</table>
<table>
<tr>
<td>Column1 data</td>
<td></td>
<td>Column3 data</td>
</tr>
</table>
<div class="para align-center">Between</div>
<div class="para align-center">____________________</div>