RE: [xsl] Split a string and fill it in a table (xslt1.0)

Subject: RE: [xsl] Split a string and fill it in a table (xslt1.0)
From: "Hofman, Peter" <peter.hofman@xxxxxxxxxxxxx>
Date: Fri, 17 Aug 2007 14:50:06 +0200
>-----Original Message-----
>From: christoph.naber@xxxxxxxxxxxxxxxxxxx
>[mailto:christoph.naber@xxxxxxxxxxxxxxxxxxx]
>Sent: vrijdag 17 augustus 2007 14:33
>To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>Subject: RE: [xsl] Split a string and fill it in a table (xslt1.0)
>
>> This is what I can come up with.
>
>Thank you for this fully adjustable template. I think I'll
>adopt much of it since I have to deal quite often with
>matrices the next time.
>
>> Basically the same thing, only I implemented your eater
>template a bit
>> different (with recursion), allowing different row sizes.
>
>Nice solution, I like the separation between "get-elements"
>and "output-elements".
>
>One question: I see you used "string-length($list) &gt; 0". Is
>it better than "not($list = '')"?

I just choose what popped up in my head. I guess "$list != ''" will also
work and is even shorter :-)

>
>Thank you!
>
>Greetings
>Christoph
>
>
>>
>> This stylesheet works with msxsl. No extension functions used.
>>
>> To do: Some checks need to be added to check for empty strings when
>> entering a templated. But I leave that up to you.
>>
>> <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet
>> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>> version="1.0">
>>
>>   <xsl:output encoding="UTF-8" method="xml" indent="yes"/>
>>
>>   <xsl:template match="/">
>>     <xsl:apply-templates/>
>>   </xsl:template>
>>
>>   <xsl:template match="root">
>>     <xsl:apply-templates/>
>>   </xsl:template>
>>
>>   <xsl:template match="transform">
>>     <xsl:call-template name="make-table">
>>       <xsl:with-param name="list" select="normalize-space(text())"/>
>>     </xsl:call-template>
>>   </xsl:template>
>>
>>   <xsl:template name="make-table">
>>     <xsl:param name="list"/>
>>     <xsl:param name="row-size" select="4"/>
>>     <table>
>>       <xsl:call-template name="output-rows">
>>         <xsl:with-param name="list" select="$list"/>
>>         <xsl:with-param name="row-size" select="$row-size"/>
>>       </xsl:call-template>
>>     </table>
>>   </xsl:template>
>>
>>   <xsl:template name="output-rows">
>>     <xsl:param name="list"/>
>>     <xsl:param name="row-size"/>
>>     <xsl:if test="string-length($list) &gt; 0">
>>       <xsl:variable name="elements-list">
>>         <xsl:call-template name="get-elements">
>>           <xsl:with-param name="list" select="$list"/>
>>           <xsl:with-param name="count" select="$row-size"/>
>>         </xsl:call-template>
>>       </xsl:variable>
>>       <xsl:comment><xsl:value-of
>select="$elements-list"/></xsl:comment>
>>       <tr>
>>         <xsl:call-template name="output-elements">
>>           <xsl:with-param name="elements-list"
>select="$elements-list"/>
>>         </xsl:call-template>
>>       </tr>
>>       <xsl:call-template name="output-rows">
>>         <xsl:with-param name="list"
>> select="substring-after($list,$elements-list)"/>
>>         <xsl:with-param name="row-size" select="$row-size"/>
>>       </xsl:call-template>
>>     </xsl:if>
>>   </xsl:template>
>>
>>   <xsl:template name="output-elements">
>>     <xsl:param name="elements-list"/>
>>     <td>
>>       <xsl:value-of select="substring-before($elements-list,' ')"/>
>>     </td>
>>     <xsl:if test="substring-after($elements-list,' ')!=''">
>>       <xsl:call-template name="output-elements">
>>         <xsl:with-param name="elements-list"
>> select="substring-after($elements-list,' ')"/>
>>       </xsl:call-template>
>>     </xsl:if>
>>   </xsl:template>
>>
>>   <xsl:template name="get-elements">
>>     <xsl:param name="list"/>
>>     <xsl:param name="count"/>
>>     <xsl:if test="$count &gt; 0">
>>       <xsl:variable name="elements-list">
>>         <xsl:call-template name="get-elements">
>>           <xsl:with-param name="list" select="substring-after($list,'
>> ')"/>
>>           <xsl:with-param name="count" select="$count - 1"/>
>>         </xsl:call-template>
>>       </xsl:variable>
>>       <xsl:value-of
>select="concat(substring-before(concat($list,' '),'
>> '),' ',$elements-list)"/>
>>     </xsl:if>
>>   </xsl:template>
>> </xsl:stylesheet>
>> Regards,
>> Peter
>>
>>
>> >-----Original Message-----
>> >From: christoph.naber@xxxxxxxxxxxxxxxxxxx
>> >[mailto:christoph.naber@xxxxxxxxxxxxxxxxxxx]
>> >Sent: vrijdag 17 augustus 2007 11:19
>> >To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>> >Subject: [xsl] Split a string and fill it in a table (xslt1.0)
>> >
>> >Hello list,
>> >
>> >(XSLT 1.0, afaik MSXML (I dont use the stylesheets, they
>are included
>> >in some visual basic programs)) I wonder about whats a good way to
>> >split a string at whitespaces and fill it into a table
>which has four
>> >rows and four columns. The string contains a transformation-matrix
>> >and for better visualization I have to put it into a html-table.
>> >
>> >I know how to split strings, but how do I put them in rows
>each with
>> >four cells? I cannot use extensionfunctions like node-set
>which would
>> >IMHO make things much easier.
>> >
>> >The example input XML:
>> >
>> ><root>
>> >        <transform>12 34 1 5 54 2 6 24 34 34 6 23 67 234 74.45
>> >2</transform> </root>
>> >
>> >Desired output:
>> ><table>
>> >        <tr>
>> >                <td>12</td>
>> >                <td>34</td>
>> >                <td>1</td>
>> >                <td>5</td>
>> >        </tr>
>> >        <tr>
>> >                <td>54</td>
>> >                <td>2</td>
>> >                <td>6</td>
>> >                <td>24</td>
>> >        </tr>
>> >        <tr>
>> >                <td>34</td>
>> >                <td>34</td>
>> >                <td>6</td>
>> >                <td>23</td>
>> >        </tr>
>> >        <tr>
>> >                <td>67</td>
>> >                <td>234</td>
>> >                <td>74.45</td>
>> >                <td>2</td>
>> >        </tr>
>> ></table>
>> >
>> >I have a working solution, but I like to know if there is a better
>> >way to do this.
>> >
>> >Here is my stylesheet:
>> >
>> ><xsl:template match="transform">
>> >        <table>
>> >                <xsl:call-template name="row">
>> >                        <xsl:with-param name="string"
>> >select="text()" />
>> >                </xsl:call-template>
>> >        </table>
>> ></xsl:template>
>> >
>> ><!-- create a row and pass the string to the element template.
>
>> >recursive call the row-template with the already used elements
>
>> >chopped off as long as string contains whitespaces -->
><xsl:template
>> >name="row">
>> >        <xsl:param name="string" select="string('')" />
>> >        <xsl:variable name="shorter">
>> >                <xsl:call-template name="eater">
>> >                        <xsl:with-param name="string"
>> >select="$string" />
>> >                </xsl:call-template>
>> >        </xsl:variable>
>> >
>> >        <xsl:if test="contains($string, ' ')">
>> >                <tr>
>> >                        <xsl:call-template name="element">
>> >                                <xsl:with-param name="string"
>> >select="$string" />
>> >                        </xsl:call-template>
>> >                </tr>
>> >                <xsl:if test="contains($shorter, ' ')" >
>> >                        <xsl:call-template name="row">
>> >                                <xsl:with-param name="string"
>> >select="$shorter" />
>> >                        </xsl:call-template>
>> >                </xsl:if>
>> >        </xsl:if>
>> >
>> ></xsl:template>
>> >
>> ><!-- create 4 cells by recursive calls to the element-template
>
>> >--> <xsl:template name="element">
>> >        <xsl:param name="string" select="string('')" />
>> >        <xsl:param name="count" select="0" />
>> >
>> >        <xsl:choose>
>> >                <!-- when 3 cells are done, output the last
>
>> >element in the row and no recursive call -->
>> >                <xsl:when test="$count > 2 and
>contains($string, ' ')">
>> >                        <td><xsl:value-of
>> >select="substring-before($string, ' ')" /></td>
>> >                </xsl:when>
>> >
>> >                <!-- output the last element in the string
>>when
>> $string contains no more whitespaces -->
>> >                <xsl:when test="not(contains($string, ' '))">
>> >                        <td><xsl:value-of select="$string" /></td>
>> >                </xsl:when>
>> >
>> >                <!-- output the next element and recursive
>>call
>> the element template with the shortened string -->
>> >                <xsl:otherwise>
>> >                        <td><xsl:value-of
>> >select="substring-before($string, ' ')" /></td>
>> >                        <xsl:call-template name="element">
>> >                                <xsl:with-param name="string"
>> >select="substring-after($string, ' ')" />
>> >                                <xsl:with-param name="count"
>> >select="$count + 1" />
>> >                        </xsl:call-template>
>> >                </xsl:otherwise>
>> >        </xsl:choose>
>> ></xsl:template>
>> >
>> ><!-- "eat" 4 elements at the beginning of the string -->
>> ><xsl:template name="eater" >
>> >        <xsl:param name="string" select="string('')" />
>> >        <xsl:value-of
>> >select="substring-after(substring-after(substring-after(substri
>> ng-after($string,
>> >' '), ' '), ' '), ' ')" />
>> ></xsl:template>
>> >
>> >Greetings Christoph
>> >
>> >
>> >
>> >If you are not the intended addressee, please inform us immediately
>> >that you have received this e-mail by mistake and delete
>it. We thank
>> >you for your support.
>> >
>> >
>>
>>
>> This e-mail and any attachment is for authorised use by the intended
>> recipient(s) only. It may contain proprietary material, confidential
>> information and/or be subject to legal privilege. It should not be
>> copied, disclosed to, retained or used by, any other party.
>If you are
>> not an intended recipient then please promptly delete this
>e- mail and
>> any attachment and all copies and inform the sender. Thank you.
>>
>
>
>
>If you are not the intended addressee, please inform us
>immediately that you have received this e-mail by mistake and
>delete it. We thank you for your support.

Current Thread