Adding a Parent tag to existing elements?
Is there a way to add a parent tag to an existing set of nodes?
Example:
<root>
<c>
<d></d>
<e>
<f></f>
</e>
<b></b>
<b></b>
<b></b>
</c>
</root>
Desired output:
<root>
<c>
<d></d>
<e>
<f></f>
</e>
<a>
开发者_如何学编程 <b></b>
<b></b>
<b></b>
</a>
</c>
</root>
Thanks!
@empo's answer only works in very simple cases and not with an XML document like this:
<root>
<c>
<d></d>
<e>
<f></f>
</e>
<b></b>
<b></b>
<b></b>
</c>
<b></b>
<b></b>
</root>
Here, if we want to wrap every group of consecutive b
s within an a
, one way to achieve this is:
<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="b"
use="generate-id(preceding-sibling::*[not(self::b)][1])"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b[not(preceding-sibling::*[1][self::b])]">
<a>
<xsl:copy-of select=
"key('kFollowing', generate-id(preceding-sibling::*[1]))"/>
</a>
</xsl:template>
<xsl:template match="b"/>
</xsl:stylesheet>
when this transformation is applied on the above XML document, the wanted correct result (all groups of consecutive b
s are wrapped in an a
) is produced:
<root>
<c>
<d/>
<e>
<f/>
</e>
<a>
<b/>
<b/>
<b/>
</a>
</c>
<a>
<b/>
<b/>
</a>
</root>
Hopefully your XML now reflects much better your real case, you can use:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/c/b[1]">
<a>
<xsl:copy-of select="self::*|following::b"/>
</a>
</xsl:template>
<xsl:template match="b"/>
</xsl:stylesheet>
You could use an identity transform and do this:
<xsl:template match="root">
<root>
<a>
<xsl:apply-templates/>
</a>
</root>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
精彩评论