Subject: Re: parameter lost in tunnel?
From: "Dan Ochs" <dan.ochs@xxxxxxxxx>
Date: Thu, 24 Jul 2008 18:12:20 -0700
|
I'm not using xsl 2.0 and have taken a bit of a different, somewhat
linear approach, but this should work for what you are trying to do:
xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="doc/sect_break[1]"/>
</xsl:template>
<xsl:template match="sect_break">
<xsl:variable name="depth" select="./@depth"/>
<xsl:variable name="next_depth"
select="(following-sibling::sect_break)[1]/@depth"/>
<xsl:variable name="elementName" select="concat('level',$depth)"/>
<xsl:choose>
<xsl:when test="$next_depth > $depth">
<xsl:element name="{$elementName}">
<xsl:apply-templates select="(following-sibling::sect_break)[1]"/>
</xsl:element>
<xsl:apply-templates
select="(following-sibling::sect_break[@depth = $depth])[1]"/>
</xsl:when>
<xsl:when test="$next_depth = $depth">
<xsl:element name="{$elementName}"/>
<xsl:apply-templates select="(following-sibling::sect_break)[1]"/>
</xsl:when>
<xsl:otherwise><xsl:element name="{$elementName}"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
input:
<doc>
<sect_break depth="1"/>
<sect_break depth="2"/>
<sect_break depth="2"/>
<sect_break depth="3"/>
<sect_break depth="1"/>
</doc>
output:
<level1>
<level2/>
<level2>
<level3/>
</level2>
</level1>
<level1/>
thanks, dan
--
Dan Ochs, Principal Consultant
Wrycan Inc.
http://xsl.wrycan.com
dan(dot)ochsatwrycan(dot)com
On Sun, Jul 20, 2008 at 10:09 AM, tom s <tshmit@xxxxxxxxx> wrote:
> Hi List,
>
> I've been struggling for more hours than I care to admit on a simple task - passing a parameter through a series of templates using tunnel="yes". For some reason my parameter seems to be lost along the way and inevitably ends up with the default value (0).
>
> In the abbreviated "sect_break" template below=2C the param "prev_depth" should start out at 0 then be set to 1 as it's passed through apply-templates the first time. But the next time sect_break is called prev_depth is 0 (or whatever default is specified in the param's select):
>
> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:fn="http://www.w3.org/2005/xpath-functions";>
> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
> <xsl:template match="/">
> <xsl:apply-templates/>
> </xsl:template>
>
> <xsl:template match="sect_break">
> <!-- prev_depth is the depth that we were at before encountering this sect_break -->
> <xsl:param name="prev_depth" select="0" tunnel="yes"/>
> <!-- depth is the depth indicated in the current sect_break -->
> <xsl:variable name="depth" select="./@depth" as="xs:integer"/>
> <xsl:variable name="direction" select="$depth - $prev_depth" as="xs:integer"/>
> <xsl:choose>
> <xsl:when test="$direction > 0">
> <!-- going deeper in depth -->
> sect_break depth=<xsl:value-of select="$depth"/>
> <xsl:apply-templates>
> <xsl:with-param name="prev_depth" select="$depth" tunnel="yes" />
> </xsl:apply-templates>
> </xsl:when>
> <!-- some other cases have been omitted for brevity -->
> </xsl:choose>
> </xsl:template>
>
> </xsl:stylesheet>
>
> Sample input:
> <doc>
> <sect_break depth="1"/>
> <sect_break depth="2"/>
> <sect_break depth="2"/>
> <sect_break depth="3"/>
> <sect_break depth="1"/>
> </doc>
>
> (fwiw, the objective is to create a nested hierarchy from one that is defined unnested. eg:
>
> <level 1>
> <level 2>
> <level 2>
> <level 3>
> <level 1>
>
> becomes:
>
> <level 1>
> <level 2>
> </level>
> <level 2>
> <level 3>
> </level>
> </level>
> </level>
> <level 1>
> </level>
> )
>
> Thanks very much for any help!
>
> --Tom
|