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

Re: String parsing, node creation

Subject: Re: String parsing, node creation
From: Mike Brown <mike@xxxxxxxx>
Date: Tue, 26 Feb 2002 14:35:46 -0700 (MST)
xsl string to node
Michael Clark wrote:
> Hello, and thanks in advance for reading my question!
> 
> I'll jump right into the code, since it explains itself better than I can.
> 
> <!-- My source XML -->
> <doc>
> 	<txt>
> 		This will be a fairly large block of text.
> 		Text block text block text block text block.
> 		It will go on for a while ... then stop.
> 	</txt>
> </doc>
> 
> The problem I have now, is as follows: My <txt> nodes may only have #text
> nodes of a certain, very short length (say, 38 characters).
> 
> So, after proper translation my xml document should look as follows:
> 
> <doc>
> 	<txt>This will be a 256 char block of text.</txt>
> 	<txt> Text block text block text block text</txt>
> 	<txt> block.  It will go on for a while ...</txt>
> 	<txt>then stop.</txt>
> </doc>
> 
> The real hitch is the #text must be broken up by word blocks (words
> tokenized by space (' '), not purely by character length.

I'll assume you are just asking for word wrap, and don't really
need, as your example suggests, left-padding of certain lines
(but not all of them) with spaces to reach 38 character widths.

The following is not the exact solution you need, but it only requires
a small amount of tweaking to emit the enclosing elements for each line.
I'd be interested to know if there's an easier way.

To use it, just call the wrap-multiline template, passing it the 'text'
variable containing the text to wrap, and setting the 'maxwidth' variable to
the column width desired (I use a top-level param for this, so I can set it
externally):

  <!-- max width to wrap to -->
  <xsl:param name="maxwidth" select="78"/>

  <!-- split lines at n characters without truncating words -->
  <!-- and preserve existing linefeeds -->
  <xsl:template name="wrap-multiline">
    <xsl:param name="text"/>
    <xsl:choose>
      <xsl:when test="contains($text,'&#10;')">
        <xsl:call-template name="justify">
          <xsl:with-param name="width" select="$maxwidth"/>
          <xsl:with-param name="txt" select="substring-before($text,'&#10;')"/>
        </xsl:call-template>
        <xsl:text>&#10;</xsl:text>
        <xsl:call-template name="wrap-multiline">
          <xsl:with-param name="text" select="substring-after($text,'&#10;')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$text">
        <xsl:call-template name="justify">
          <xsl:with-param name="width" select="$maxwidth"/>
          <xsl:with-param name="txt" select="$text"/>
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="justify">
    <xsl:param name="txt" /> 
    <xsl:param name="width" /> 
    <xsl:choose>
      <xsl:when test="$width &lt; string-length($txt)">
        <xsl:variable name="real-width">
          <xsl:call-template name="tune-width">
            <xsl:with-param select="$txt" name="txt" /> 
            <xsl:with-param select="$width" name="width" /> 
            <xsl:with-param select="$width" name="def" /> 
          </xsl:call-template>
        </xsl:variable>
        <!--
           this is where you'd do something like
           <txt>
             <xsl:value-of select="substring($txt, 1, $real-width)"/>
           </txt>
           instead of the value-of below...
        -->
        <xsl:value-of select="concat(substring($txt, 1, $real-width),'&#10;')" /> 
        <xsl:call-template name="justify">
          <xsl:with-param select="substring($txt,$real-width + 1)" name="txt" /> 
          <xsl:with-param select="$width" name="width" /> 
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$txt"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="tune-width">
    <xsl:param name="txt" /> 
    <xsl:param name="width" /> 
    <xsl:param name="def" /> 
    <xsl:choose>
      <xsl:when test="$width = 0">
        <xsl:value-of select="$def" /> 
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="substring($txt, $width, 1 ) = ' '">
            <xsl:value-of select="$width" /> 
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="tune-width">
              <xsl:with-param select="$txt" name="txt" /> 
              <xsl:with-param select="$width - 1" name="width" /> 
              <xsl:with-param select="$def" name="def" /> 
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

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


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.