Re: [xsl] variable outside a for-each loop: second try

Subject: Re: [xsl] variable outside a for-each loop: second try
From: "Mathieu Malaterre" <mathieu.malaterre@xxxxxxxxx>
Date: Thu, 20 Sep 2007 16:44:09 +0200
Hi Brad,

  Sorry to not have been more verbose. Here is a more complete
example. Only the first column is allowed to be empty. All other are
non-emtpy. There can be any aribtrary empty col#1 (so looking at only
the very preceeding row will not work).

<?xml version="1.0"?>
<table>
  <row>
    <entry>
      <para>Col1 A</para>
    </entry>
    <entry>
      <para>Col2 A</para>
    </entry>
  </row>
  <row>
    <entry>
      <para/>
    </entry>
    <entry>
      <para>Col2 B</para>
    </entry>
  </row>
  <row>
    <entry>
      <para/>
    </entry>
    <entry>
      <para>Col2 C</para>
    </entry>
  </row>
  <row>
    <entry>
      <para>Col1 D</para>
    </entry>
    <entry>
      <para>Col2 D</para>
    </entry>
  </row>
  ...
</table>


It looks like my problem is getting too complex. So I am thinking that
my initial design is poor. Since I have control over the output
format, I am thinking that I could also generate:

<table>
   <col1 name="Col1 A">
     <col2 name="Col2 A"/>
     <col2 name="Col2 B"/>
     <col2 name="Col2 C"/>
   </col1>
   <col1 name="Col1 D">
     <col2 name="Col2 D"/>
   </col1>
  ...
 </table>

I am grouping by common col1 all my entries. It should be slightly
smarted to parse afterward.

Thanks again
-Mathieu

On 9/20/07, Bjorndahl, Brad <brad.bjorndahl@xxxxxxxxxxxxxxxx> wrote:
> 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
>
>


-- 
Mathieu

Current Thread