This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: How to avoid applying templates several times to the same descendant
- To: <xsl-list at lists dot mulberrytech dot com>
- Subject: RE: [xsl] How to avoid applying templates several times to the same descendant
- From: "Jarno Elovirta" <jarno at codeonline dot com>
- Date: Tue, 8 May 2001 10:55:58 +0300
- Reply-To: xsl-list at lists dot mulberrytech dot com
Heippa!
> The "spec" I got sounded like this:
> "If we find any element inside ATLAS or EARTH with an attribute ATTR not
>
> null, generate as many ATLAS/EARTH elements (duplicates) as the number
> of different values of the ATTR attribute. Put this value in the ATTR
> attribute of the ATLAS/EARTH and delete all elements where ATTR does not
>
> correspond to its ATLAS/EARTH."
How about
[c:\temp]type test.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<ATLAS>
<PROC>
<PAR ATTR="Subject III">
Blabla 1
</PAR>
<PAR>
Blabla 0
</PAR>
</PROC>
<PROC ATTR="Subject I">
Blabla 2
</PROC>
<PAR ATTR="Subject II">
Blabla 3
</PAR>
<PROC>
<PAR ATTR="Subject II">
Blabla 4
</PAR>
</PROC>
</ATLAS>
[c:\temp]type test.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
indent="yes" />
<xsl:key name="UniqueATTR" match="*[@ATTR]" use="@ATTR"/>
<xsl:template match="ATLAS">
<xsl:for-each select=".//*[@ATTR and
generate-id(.)=generate-id(key('UniqueATTR', @ATTR))]">
<xsl:variable name="ATTR" select="@ATTR" />
<xsl:for-each select="/ATLAS">
<xsl:copy>
<xsl:copy-of select="$ATTR" />
<xsl:apply-templates select="node()">
<xsl:with-param name="ATTR" select="$ATTR" />
</xsl:apply-templates>
</xsl:copy>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="*">
<xsl:param name="ATTR" />
<xsl:if test="not(@ATTR) or @ATTR = $ATTR">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="node()">
<xsl:with-param name="ATTR" select="$ATTR" />
</xsl:apply-templates>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)" />
</xsl:template>
</xsl:stylesheet>
[c:\temp]saxon test.xml test.xsl
<?xml version="1.0" encoding="utf-8"?>
<ATLAS ATTR="Subject III">
<PROC>
<PAR ATTR="Subject III">Blabla 1</PAR>
<PAR>Blabla 0</PAR>
</PROC>
<PROC/>
</ATLAS>
<ATLAS ATTR="Subject I">
<PROC>
<PAR>Blabla 0</PAR>
</PROC>
<PROC ATTR="Subject I">Blabla 2</PROC>
<PROC/>
</ATLAS>
<ATLAS ATTR="Subject II">
<PROC>
<PAR>Blabla 0</PAR>
</PROC>
<PAR ATTR="Subject II">Blabla 3</PAR>
<PROC>
<PAR ATTR="Subject II">Blabla 4</PAR>
</PROC>
</ATLAS>
Which should be what you wanted, except it normalizes the whitespace in text
nodes. There are better solutions, but hope this helps,
Jarno - Assemblage 23: Love My Way
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list