[xsl] variable scope

Subject: [xsl] variable scope
From: "Greg Fausak" <lgfausak@xxxxxxxxx>
Date: Thu, 21 Aug 2008 19:12:53 -0500
Hi there!

I've got a situation where an attribute may or
may not be set.  I'm building a postgres ddl from xml source that looks like:

...
<views>
  <view name="super.av_address" source="super"/>
  <view name="brand.av_address" source="brand"/>
  <view name="av_address" source="agentviaconsumer" schema="agent" />
  <view name="av_address" source="consumer" schema="consumer"/>
  <view name="av_address" source="fast_consumer" schema="fast_consumer"/>
</views>
...

(Warning: I am going to use the term 'schema' in a postgres relational
context in
this paragraph, not the xml context!).  Sometimes I have a view name which
contains the schema in the name attribute, like the first two above.
Then sometimes
I have the schema defined in the schema attribute, like the last
three.  It's easy enough
to get the data from the attributes into variables sname and vname like:

        <xsl:for-each select="//views/view">
                <xsl:choose>
                        <xsl:when test="@source = 'super'">
                                <xsl:choose>
                                        <xsl:when test="@schema">
                                                <xsl:variable
name="sname" select="@schema"/>
                                                <xsl:variable
name="vname" select="@name"/>
                                                <xsl:variable
name="tname" select="str:replace($vname,'av_','at_')"/>
                                                <xsl:call-template
name="create-super-view">

<xsl:with-param name="schemaname" select="$sname"/>

<xsl:with-param name="viewname" select="$vname"/>

<xsl:with-param name="tablename" select="$tname"/>
                                                </xsl:call-template>
                                        </xsl:when>
                                        <xsl:when test="contains(@name,'.')">
                                                <xsl:variable
name="sname" select="str:split(@name,'.')[1]"/>
                                                <xsl:variable
name="vname" select="str:split(@name,'.')[2]"/>
                                                <xsl:variable
name="tname" select="str:replace($vname,'av_','at_')"/>
                                                <xsl:call-template
name="create-super-view">

<xsl:with-param name="schemaname" select="$sname"/>

<xsl:with-param name="viewname" select="$vname"/>

<xsl:with-param name="tablename" select="$tname"/>
                                                </xsl:call-template>
                                        </xsl:when>
                                        <xsl:otherwise>
                                <xsl:message terminate="yes">
Cannot create view 'super' on: <xsl:value-of select="@name"/> without
schema definition.
                                </xsl:message>
                                        </xsl:otherwise>
                                </xsl:choose>
                        </xsl:when>
                        <xsl:when test="@source = 'brand'">
                                <xsl:choose>
                                        <xsl:when test="@schema">
                                                <xsl:variable
name="sname" select="@schema"/>
                                                <xsl:variable
name="vname" select="@name"/>
                                                <xsl:variable
name="tname" select="str:replace($vname,'av_','at_')"/>
                                                <xsl:call-template
name="create-brand-view">

<xsl:with-param name="schemaname" select="$sname"/>

<xsl:with-param name="viewname" select="$vname"/>

<xsl:with-param name="tablename" select="$tname"/>
                                                </xsl:call-template>
                                        </xsl:when>
                                        <xsl:when test="contains(@name,'.')">
                                                <xsl:variable
name="sname" select="str:split(@name,'.')[1]"/>
                                                <xsl:variable
name="vname" select="str:split(@name,'.')[2]"/>
                                                <xsl:variable
name="tname" select="str:replace($vname,'av_','at_')"/>
                                                <xsl:call-template
name="create-brand-view">

<xsl:with-param name="schemaname" select="$sname"/>

<xsl:with-param name="viewname" select="$vname"/>

<xsl:with-param name="tablename" select="$tname"/>
                                                </xsl:call-template>
                                        </xsl:when>
                                        <xsl:otherwise>
                                <xsl:message terminate="yes">
Cannot create view 'super' on: <xsl:value-of select="@name"/> without
schema definition.
                                </xsl:message>
                                        </xsl:otherwise>
                                </xsl:choose>
                        </xsl:when>
...etc...


However, it would be so much more readable if I could do the variable assignment
one time, something like:

                                <xsl:choose>
                                        <xsl:when test="@schema">
                                                <xsl:variable
name="sname" select="@schema"/>
                                                <xsl:variable
name="vname" select="@name"/>
                                                <xsl:variable
name="tname" select="str:replace($vname,'av_','at_')"/>
                                        </xsl:when>
                                        <xsl:when test="contains(@name,'.')">
                                                <xsl:variable
name="sname" select="str:split(@name,'.')[1]"/>
                                                <xsl:variable
name="vname" select="str:split(@name,'.')[2]"/>
                                                <xsl:variable
name="tname" select="str:replace($vname,'av_','at_')"/>
                                        </xsl:when>
                                        <xsl:otherwise>
                                <xsl:message terminate="yes">
Cannot create view 'super' on: <xsl:value-of select="@name"/> without
schema definition.
                                </xsl:message>
                                        </xsl:otherwise>
                                </xsl:choose>

        <xsl:for-each select="//views/view">
                <xsl:choose>
                        <xsl:when test="@source = 'super'">
                                                <xsl:call-template
name="create-super-view">

<xsl:with-param name="schemaname" select="$sname"/>

<xsl:with-param name="viewname" select="$vname"/>

<xsl:with-param name="tablename" select="$tname"/>
                                                </xsl:call-template>
                        </xsl:when>
                        <xsl:when test="@source = 'brand'">
                                                <xsl:call-template
name="create-brand-view">

<xsl:with-param name="schemaname" select="$sname"/>

<xsl:with-param name="viewname" select="$vname"/>

<xsl:with-param name="tablename" select="$tname"/>
                                                </xsl:call-template>
                        </xsl:when>
...etc...

but I can't get the variables that are set first
to be visible to the later for loop?

Can anyone offer an idea?  I am using xsltproc, which is version 1.0.

Thank you,
-g

-- 
Greg Fausak
greg@xxxxxxxxxxxx

Current Thread