-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This is the first time I have looked at XSLT in anger and have what I thought
was a simple question.
Given an input document containing amongst other things a recurring element I
would like to create a container element in the output document. To my mind
this was a case of output an opening container tag prior to the first
occurrent of the recurrent element and a closing tag after the last
occurrence.
When I first approached this I tried using something such as
<xsl:if test="postion() = 1">
<container>
</xsl:if>
but this complained as it was not valid XML.
Upon seeking advice from a colleague it was suggested I use modes to control
the output and output the container element in the template matching the
first element. Given the following test document
<foo>
<bar id="bar-1">
<barfoo id="barfoo-1"/>
</bar>
<bar id="bar-2">
<barfoo id="barfoo-2"/>
</bar>
<bar id="bar-3">
<barfoo id="barfoo-3"/>
</bar>
</foo>
My XSL looked like the following:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xslt" exclude-result-prefixes="xalan">
<xsl:output method="xml" indent="yes" xalan:indent-amount="2" />
<xsl:template match="foo">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="bar[1]">
<xsl:element name="container">
<xsl:apply-templates select="../bar" mode="standard"/>
</xsl:element>
</xsl:template>
<xsl:template match="bar" mode="standard">
<xsl:element name="foobar">
<xsl:attribute name="id">
<xsl:value-of select="@id"/>
</xsl:attribute>
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="barfoo">
<xsl:element name="barfoo">
<xsl:value-of select="@id"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The following is my resulting document:
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<container>
<foobar id="bar-1">
<barfoo>barfoo-1</barfoo>
</foobar>
<foobar id="bar-2">
<barfoo>barfoo-2</barfoo>
</foobar>
<foobar id="bar-3">
<barfoo>barfoo-3</barfoo>
</foobar>
</container>
<barfoo>barfoo-2</barfoo>
<barfoo>barfoo-3</barfoo>
</foo>
Which seems to have spurious <barfoo> elements following the closing
</container> element. From my continued efforts I seem to have this down to
the behaviour when using the mode and I can resolve this be added the mode
attribute to my <barfoo> template match. I am suprised I need this as I would
have thought it would work without this.
I would appreciate any help anyone can give regarding this. How should this be
done and any explanation as to why this occurs.
FYI - the following is the required information regarding the xslt engine I am
using which for this was Xalan-J 2.5.2
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:msxsl="http://www.w3.org/TR/WD-xsl"><head><title>XSLT Processor
Version</title></head><body><msxsl:choose><msxsl:when
test="."/><msxsl:otherwise><p>Vendor: Apache Software Foundation<br/>Vendor
URL:
http://xml.apache.org/xalan-j</p></msxsl:otherwise></msxsl:choose></body></html>
- --
Rob Exley <rob(_dot_)exley(_at_)equifax(_dot_)com>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
iD8DBQFAcp0bIQSbu4H8vOQRAjRFAJ4v5J+7uHGAfZbcXuNtnI6DOiY1EACfbOqY
R2d67/fWJCit11WOpF/dNC8=
=5Agl
-----END PGP SIGNATURE-----