xsl-list
[Top] [All Lists]

Re: parsing a long string into chunks

2003-04-10 13:47:05
Here's the second part -- how to split the result into a number of
polylines, each having not more than a predefined maximum number of points:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:vendor="urn:schemas-microsoft-com:xslt"
 exclude-result-prefixes="vendor"


   <xsl:import href="strSplit-to-Words.xsl"/>
<!-- This transformation must be applied to:
        testSplitToWords6.xml
-->

   <xsl:output indent="yes" omit-xml-declaration="yes"/>

   <xsl:param name="pmaxPoints" select="2"/>

    <xsl:template match="/">
      <lines>
      <xsl:variable name="vrtfPoints">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="/*/*"/>
          <xsl:with-param name="pDelimiters"
                          select="' &#10;&#13;'"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="vPoints"
           select="vendor:node-set($vrtfPoints)/*"/>

        <xsl:for-each
         select="$vPoints[position() mod $pmaxPoints = 1]">
          <polyline>
           <xsl:apply-templates
               select=". | following-sibling::*
                             [position() &lt; $pmaxPoints]"/>
          </polyline>
        </xsl:for-each>
      </lines>
    </xsl:template>

    <xsl:template match="word">
      <xsl:if test="string(.)">
        <point x="{substring-before(., ',')}" y="{substring-after(.,
',')}"/>
      </xsl:if>
    </xsl:template>
</xsl:stylesheet>

When this transformation is applied on this (longer) source.xml:

<poly>
  <coordinates>10,10 10,20 20,20 11,12 13,14 15,16 17,18</coordinates>
</poly>

The wanted result is produced:

<lines>
  <polyline>
    <point x="10" y="10" />
    <point x="10" y="20" />
  </polyline>
  <polyline>
    <point x="20" y="20" />
    <point x="11" y="12" />
  </polyline>
  <polyline>
    <point x="13" y="14" />
    <point x="15" y="16" />
  </polyline>
  <polyline>
    <point x="17" y="18" />
  </polyline>
</lines>


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

"Dimitre Novatchev" <dnovatchev(_at_)yahoo(_dot_)com> wrote in message
news:b74jhj$oqa$1(_at_)main(_dot_)gmane(_dot_)org(_dot_)(_dot_)(_dot_)
This is done easily with FXSL:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:vendor="urn:schemas-microsoft-com:xslt"
 exclude-result-prefixes="vendor"


   <xsl:import href="strSplit-to-Words.xsl"/>

   <xsl:output indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/">
      <xsl:variable name="vrtfPoints">
        <xsl:call-template name="str-split-to-words">
          <xsl:with-param name="pStr" select="/*/*"/>
          <xsl:with-param name="pDelimiters"
                          select="' &#10;&#13;'"/>
        </xsl:call-template>
      </xsl:variable>

      <polyline>
        <xsl:apply-templates
             select="vendor:node-set($vrtfPoints)/*"/>
      </polyline>
    </xsl:template>

    <xsl:template match="word">
      <xsl:if test="string(.)">
        <point x="{substring-before(., ',')}" y="{substring-after(.,
',')}"/>
      </xsl:if>
    </xsl:template>
</xsl:stylesheet>

When applied to your source.xml:

<poly>
  <coordinates>10,10 10,20 20,20</coordinates>
</poly>

the wanted result is produced:

<polyline>
  <point x="10" y="10" />
  <point x="10" y="20" />
  <point x="20" y="20" />
</polyline>


Hope this helped.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL


"Tim Wilkins" <Tim(_dot_)Wilkins(_at_)informatix(_dot_)co(_dot_)uk> wrote in 
message
news:000301c2ff7e$bb720850$1600040a(_at_)informatix(_dot_)co(_dot_)uk(_dot_)(_dot_)(_dot_)
I have input data of the form
<coordinates>x1,y1 x2,y2 x3,y3</coordinates>
e.g.
<coordinates>10,10 10,20 20,20</coordinates>
There can be any number of space-delimited substrings.  At present this
is
parsed using substring-before and substring-after with a recursive
template,
to generate a sequence of elements <Point X="10" Y="10"/> etc.
Unfortunately this can sometimes be slow for long lists (by which I mean
5000 or so x,y pairs).  In addition I have to divide up the resultant
list
of elements into chunks (to avoid exceeding a limit on the number of
points
in a line), although this can easily be done on a second pass (it's then
a
similar problem to splitting up for a table with a given number of
columns).

i.e. I want

<coordinates>x1,x2 ...

to become someething like (ignoring attributes for simplicity!)

<Polyline>
<Point><Point><Point><Point>
</Polyline>
<Polyline>
<Point><Point><Point><Point>
</Polyline>

Can anyone think of a better way, especially a way of splitting up
without
the need for a second pass?  What I'd really like is a trivial way to
make
xsl treat the string as a node list split at whitespace, but I suspect
that
that isn't possible!

Tim


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list






 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list






 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>