[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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: christoph.naber@xxxxxxxxxxxxxxxxxxx
Date: Fri, 17 Aug 2007 14:33:13 +0200

> 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) > 0". Is it better
than "not($list = '')"?

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