RE: [xsl] variable outside a for-each loop

Subject: RE: [xsl] variable outside a for-each loop
From: "Bjorndahl, Brad" <brad.bjorndahl@xxxxxxxxxxxxxxxx>
Date: Thu, 20 Sep 2007 10:26:01 -0400
Hi,

Something more along the lines of the following will work. I assume you want
to carry the last non-empty para content to any empty attribute in the same
relative position. Your sample data is too meagre to be sure.

Learn XPath to get to nodes in your XML.

If you change your attribute names to something like "col1', 'col2', etc.,
this can be generalised much more easily.
I'm not sure that the string-join does much in this transform.


<?xml version='1.0'?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/informaltable" >
  <table>
    <xsl:apply-templates />
  </table>
</xsl:template>

<xsl:template match="row">
  <entry>
    <xsl:for-each select="entry" >
    <xsl:variable name="position" select="position()" />
    <xsl:variable name="attName"><xsl:value-of select="('one',
'two')[$position]" /></xsl:variable>

      <xsl:attribute name="{$attName}" >
        <xsl:choose>
          <xsl:when test="para eq ''" >
            <xsl:value-of select="../preceding-sibling::row/entry[position()
eq $position][1]/normalize-space(string-join(para,' '))" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="normalize-space(string-join(para,' '))" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:for-each>
  </entry>
</xsl:template>

</xsl:transform>

Brad


-----Original Message-----
From: Mathieu Malaterre [mailto:mathieu.malaterre@xxxxxxxxx]
Sent: September 20, 2007 8:52 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] variable outside a for-each loop

Hello,

  this is clearly a question that has been asked many times on this mailing
list. But I simply cannot find anything smart to do for my
issue:

I have the following XML (docbook):

<informaltable>
  <row>
    <entry>
      <para>ABC</para>
    </entry>
    <entry>
      <para>DEF</para>
    </entry>
  </row>
  <row>
    <entry>
      <para/>
    </entry>
    <entry>
      <para>DEF 2</para>
    </entry>
  </row>
</informaltable>

My goal is to produce:

  <table>
    <entry one="ABC" two="DEF"/>
    <entry one="ABC" two="DEF 2"/>
  </table>


In C/C++ this is trivial at each step whenever row/entry is empty I would use
some local variable instead. But in XSL I am stuck with:

                <xsl:for-each select="row">
                  <xsl:variable name="one"
select="normalize-space(string-join(entry[1]/para,' '))"/>
                  <xsl:variable name="two"
select="normalize-space(string-join(entry[2]/para,' '))"/>
                  <entry one="{$one}" two="{$two}"/>
                </xsl:for-each>

Could someone please let me know what the correct solution is when using XSL
?

Thanks so much;

--
Mathieu

Current Thread