[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

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

Subject: RE: Split a string and fill it in a table (xslt1.0)
From: "Hofman, Peter" <peter.hofman@xxxxxxxxxxxxx>
Date: Fri, 17 Aug 2007 14:06:21 +0200
RE:  Split a string and fill it in a table (xslt1.0)
Hi Christoph,

After having done mostly XSLT 2.0 lately, I thought it would be nice to
try solve some XSLT 1.0 problem.

This is what I can come up with.
Basically the same thing, only I implemented your eater template a bit
different (with recursion), allowing different row sizes.
Empty elements are added to the row when not enough data is provided. If
you need a more or less columns, you
Can pass param row-size to make-table template.

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:  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.

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.