Darren Davison wrote:
given the following DOM snippet;
<root>
<sub1 foo="4">testing</sub1>
<sub1 foo="0">hello</sub1>
<sub1 foo="0">world</sub1>
<sub1>hello again</sub1>
</root>
I need to transform with XSL to something like;
start foo = 0
hello
world
end foo = 0
start foo = 4
testing
end foo = 4
hello again
The (hopefully clear) constraints are that the attribute foo is
optional and that it may be any whole number if present, though may or
may not be sequential.
Sorting the nodeset based on the value of foo I can manage (!), but I
can't figure out how to output the boundary markers shown. Can anyone
help??
I think so. Try this:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="root/sub1[@foo]">
<xsl:sort select="@foo" order="ascending"/>
</xsl:apply-templates>
<xsl:apply-templates select="root/sub1[not(@foo)]">
<xsl:sort select="@foo" order="ascending"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="sub1">
<xsl:if test="not(@foo=preceding::node()/@foo)">
<xsl:text>
</xsl:text>
<xsl:if test="@foo">
<xsl:text>start foo = </xsl:text>
<xsl:value-of select="@foo"/>
</xsl:if>
</xsl:if>
<xsl:text>
</xsl:text>
<xsl:value-of select="."/>
<xsl:if test="not(@foo=following::node()/@foo)">
<xsl:text>
</xsl:text>
<xsl:if test="@foo">
<xsl:text>end foo = </xsl:text>
<xsl:value-of select="@foo"/>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When I run that on the data you've posted, I get this output:
start foo = 0
hello
world
end foo = 0
start foo = 4
testing
end foo = 4
hello again
That's pretty close to what you wanted, if I understood you correctly.
If not, you can probably see how to modify it. If you don't actually
need the non-foo nodes at the end (and could accept them at beginning of
the output) then you can just elimate the second apply-templates in the
root template and change the select clause of the first one to be just
root/sub1.
Ed