xsl-list
[Top] [All Lists]

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

2007-09-20 07:56:06
Mathieu,
The transform I sent does not look at the immediately preceding row entry; it 
looks at the first preceding _non-empty_ row entry.
I can't comment on the rest except to say that I really like the "slightly 
smarted" expression. It can have meaning at several levels in English.

Brad


-----Original Message-----
From: Mathieu Malaterre [mailto:mathieu(_dot_)malaterre(_at_)gmail(_dot_)com]
Sent: September 20, 2007 10:44 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] variable outside a for-each loop: second try

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(_dot_)bjorndahl(_at_)thermofisher(_dot_)com> 
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(_dot_)malaterre(_at_)gmail(_dot_)com]
Sent: September 20, 2007 8:52 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--
Mathieu

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--