我。 XSLT 1.0 解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kFollowing"
match="*[not(self::static or self::header)]"
use="generate-id(preceding-sibling::*
[self::static
or
self::header
][1]
)"/>
<xsl:template match="/*[static]">
<p><xsl:value-of select="static"/></p>
<ul>
<xsl:apply-templates select="static|header"/>
</ul>
</xsl:template>
<xsl:template match="static|header">
<li>
<xsl:value-of select=
"concat(self::header, '
')"/>
<table>
<xsl:apply-templates
select="key('kFollowing', generate-id())"/>
</table>
</li>
</xsl:template>
<xsl:template match=
"*/*[not(self::static or self::header)]">
<tr>
<td>
<xsl:value-of select=
"translate(name(),'-', ' ')"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
应用于提供的 XML 文档时:
<question>
<static><![CDATA[Static Data]]></static>
<debit-row />
<debit-row />
<credit-row />
<header><![CDATA[Header HTML 1]]></header>
<debit-row />
<debit-row />
<credit-row />
</question>
产生想要的正确结果:
<p>Static Data</p>
<ul>
<li>
<table>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>credit row</td>
</tr>
</table>
</li>
<li>Header HTML 1
<table>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>credit row</td>
</tr>
</table>
</li>
</ul>
解释:位置分组使用一个键来定义属于一个组的所有元素。
二。 XSLT 2.0 解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*[static]">
<p><xsl:value-of select="static"/></p>
<ul>
<xsl:for-each-group select="*"
group-starting-with="static|header">
<li>
<xsl:value-of separator="
" select=
"current-group()[1][self::header], ''"/>
<table>
<xsl:apply-templates
select="current-group()[position() gt 1]"/>
</table>
</li>
</xsl:for-each-group>
</ul>
</xsl:template>
<xsl:template match=
"*/*[not(self::static or self::header)]">
<tr>
<td>
<xsl:value-of select=
"translate(name(),'-', ' ')"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
当这个 XSLT 2.0 转换应用于同一个 XML 文档(上图)时,同样会产生相同的正确结果:
<p>Static Data</p>
<ul>
<li>
<table>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>credit row</td>
</tr>
</table>
</li>
<li>Header HTML 1
<table>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>debit row</td>
</tr>
<tr>
<td>credit row</td>
</tr>
</table>
</li>
</ul>
说明:使用带有group-starting-with 属性的XSLT 2.0 <xsl:for-each-group> 指令。也使用标准的 XSLT 2.0 函数current-group()。