This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
collapsing consecutive elements
- From: Saverio Perugini <sperugin at csgrad dot cs dot vt dot edu>
- To: <XSL-List at lists dot mulberrytech dot com>
- Date: Fri, 18 Jan 2002 12:50:57 -0500 (EST)
- Subject: [xsl] collapsing consecutive elements
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hello,
Does anyone know of a quick and dirty way to collapse a series of
elements which each have only one child?
For example, I'd like to transform the following XML
<db>
<a>
<b>
<c>
<d/>
<e/>
</c>
</b>
</a>
<f>
<g>
<h>
<i/>
<j/>
</h>
</g>
</f>
</db>
into
<db>
<a_b_c>
<d/>
<e/>
</a_b_c>
<f_g_h>
<i/>
<j/>
</f_g_h>
</db>
The following stylesheet is close, but not quite there yet.
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:template match="node()[child::node()]" priority="0.7">
<xsl:if test="count(child::node()) = 1">
<xsl:element name='{local-name()}___{local-name(child::node())}'>
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
<xsl:if test="local-name() != 'db' and count(child::node()) > 1 and count(preceding-sibling::node()) = 0 and count(following-sibling::node()) = 0">
<xsl:apply-templates/>
</xsl:if>
<xsl:if test="count(child::node()) > 1 and (count(preceding-sibling::node()) > 0 or count(following-sibling::node()) > 0)">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
<xsl:if test="local-name() = 'db'">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="@* | node()" priority="0.6">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Many Thanks,
Saverio Perugini
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list