I will offer this solution, which uses just a key and the identity rule:
<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="kAllChildren" match="b" use=
"generate-id(
(preceding-sibling::node()
[not(self::b)][1]
|
parent::*[
*[1][self::b]
]
)
[last()]
)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()
[not(self::b)
and
following-sibling::node()[1][self::b]
]">
<xsl:copy-of select="."/>
<c>
<xsl:copy-of select="key('kAllChildren', generate-id())"/>
</c>
</xsl:template>
<xsl:template match="*[*[1][self::b]]">
<xsl:copy>
<xsl:copy-of select="@*"/>
<c>
<xsl:copy-of select="key('kAllChildren', generate-id())"/>
</c>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b"/>
</xsl:stylesheet>
It produces the correct result even with source xml like this:
<test>
<b>0</b>
<a>1</a>
<a>2</a>
<b>3</b>
<b>4</b>
5
<b>6</b>
<b>7</b>
<b>8</b>
9
<d>
<e>10</e>
<b>11</b>
<e>12</e>
<f>13</f>
<b>14</b>
<b>15</b>
16
<b>17</b>
<b>18</b>
<b>19</b>
20
</d>
21
<b>22</b>
23
</test>
Cheers,
Dimitre Novatchev
"Martin Honnen" <ma*******@yahoo.dewrote in message
news:48***********************@newsspool4.arcor-online.net...
MRe wrote:
> The closest I've come to getting this is to call a recursive
template, passing child::*[1] initially, and following-sibling::*[1]
for each recursive step, and also passing a 'block' parameter that, if
false and <bis encountered, puts a <cin and sets block to true,
and if true and <ais encountered, puts a </cin and sets to false.
However, this won't work as it won't put a </cin if the last element
is a <b>.
With XSLT 1.0 you can solve such problems by processing sibling by
sibling, here is a sample stylesheet:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/test">
<xsl:copy>
<xsl:apply-templates select="node()[1]" mode="group"/>
</xsl:copy>
</xsl:template>
<xsl:template match="test/b" mode="group">
<c>
<xsl:copy-of select="."/>
<xsl:apply-templates
select="following-sibling::node()[1][self::b]"/>
</c>
<xsl:apply-templates
select="following-sibling::node()[not(self::b)][1]" mode="group"/>
</xsl:template>
<xsl:template match="test/b">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::node()[1][self::b]"/>
</xsl:template>
<xsl:template match="test/node()[not(self::b)]" mode="group">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::node()[1]"
mode="group"/>
</xsl:template>
</xsl:stylesheet>
--
Martin Honnen
http://JavaScript.FAQTs.com/