Reputation: 4883
How can I transform nested XML elements with xslt, keeping the structure?
Let's say I have an XML document like this:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node>
</node>
<node>
<node>
<node>
</node>
</node>
</node>
</root>
And I would like to get something like this:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<element>
</element>
<element>
<element>
<element>
</element>
</element>
</element>
</root>
What kind of xslt should I use?
Thanks!
Upvotes: 2
Views: 4216
Reputation: 243449
The way to do this in XSLT is this (using the identity rule and push style):
<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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<element>
<xsl:apply-templates select="node()|@*"/>
</element>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<root>
<node>
</node>
<node>
<node>
<node>
</node>
</node>
</node>
</root>
the wanted, correct result is produced:
<root>
<element/>
<element>
<element>
<element/>
</element>
</element>
</root>
Do note:
The use of the identity rule and its overriding for only a specific element -- this is the most fundamental and powerful XSLT design pattern.
How by using 1. above we achieve ellegant and pure "push style" transformation.
Upvotes: 5
Reputation: 798626
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<root>
<xsl:apply-templates />
</root>
</xsl:template>
<xsl:template match="node">
<element>
<xsl:apply-templates />
</element>
</xsl:template>
</xsl:stylesheet>
The key is the apply-templates
tag to process the tag contents recursively.
Upvotes: 3