Reputation: 435
This is a further question to what I posted on xslt move node inside sibling node
This is my input:
<div class="a" >aaa
<div class="b">b1</div>
<div class="c">b1c1</div>
<div class="d">b1d1</div>
<div class="d">b1d2</div>
<div class="b">b2</div>
<div class="c">b2c1</div>
<div class="d">b2d1</div>
<div class="d">b2d2</div>
<div class="d">b2d3</div>
<div class="b">b3</div>
<div class="c">b3c1</div>
<div class="d">b3d1</div>
</div>
and this is the output I would like to get:
<div class="a" >aaa
<div class="b">b1
<div class="c">b1c1</div>
<div class="d">b1d1</div>
<div class="d">b1d2</div>
</div>
<div class="b">b2
<div class="c">b2c1</div>
<div class="d">b2d1</div>
<div class="d">b2d2</div>
<div class="d">b2d3</div>
</div>
<div class="b">b3
<div class="c">b3c1</div>
<div class="d">b3d1</div>
</div>
</div>
The only difference from the previous problem is that has a value, that is aaa.
I am using the following xslt:
<?xml version="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="b" match="div[@class!='b']" use="generate-id(preceding-sibling::div[@class='b'][1])" />
<!-- Identity template, copies everything as is -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Override for target element -->
<xsl:template match="div[@class='a']">
<xsl:copy>
<xsl:apply-templates select="@*|div[@class='b']"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[@class='b']">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:apply-templates select="key('b', generate-id())" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
But it gives me the following result, that is "aaa" (after div class="a") has disappeared :(
<div class="a" >
<div class="b">b1
<div class="c">b1c1</div>
<div class="d">b1d1</div>
<div class="d">b1d2</div>
</div>
<div class="b">b2
<div class="c">b2c1</div>
<div class="d">b2d1</div>
<div class="d">b2d2</div>
<div class="d">b2d3</div>
</div>
<div class="b">b3
<div class="c">b3c1</div>
<div class="d">b3d1</div>
</div>
</div>
What am I doing wrong? I thank you in advance for your help.
Upvotes: 0
Views: 86
Reputation: 70618
The problem is with this line, in the template that matches "div[@class='a']"
<xsl:apply-templates select="@*|div[@class='b']"/>
This select attributes, and divs with class "b", but it does not select anything else, including text nodes. Replace it with this to select your "aaa" text
<xsl:apply-templates select="@*|text()|div[@class='b']"/>
Alternatively, this would also work
<xsl:apply-templates select="@*|node() except div[@class !='b']"/>
Upvotes: 1