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

Re: Format text within a XML tag...

Subject: Re: Format text within a XML tag...
From: Peter Davis <pdavis152@xxxxxxxxx>
Date: Tue, 18 Jun 2002 03:02:52 -0700
formatting text in xml
Hash: SHA1

On Tuesday 18 June 2002 02:15, Anders Wasen wrote:
> I have looked into solving it with a script and deviding the string into
> peaces like rule/comment and then add text formating tags around the
> comment part(s), but the problem is that I don't know how many comments
> there is... this will only support one comment:

First, you are not using XSLT, you are using WD-XSL.  The <xsl:eval> tag 
doesn't exist in XSLT.  Since I don't know WD-XSL, my attempted solution will 
be in pure XSLT.  Please feel free to disregard my suggestions, since you 
will likely get better performance (but not portability) using an extension 
function; if you wish to continue to use VBScript, you may do so.  The 
concept of the loop I describe can be adapted to any language, not just XSLT.

What you need is a loop: search for the leading "/*", output the text before 
that "/*", output some formatting tags, search for the closing "*/", output 
the text between the previous "/*" and that "*/", output some formatting 
tags, and repeat.  In XSLT, you can make such a loop with a recursive 
template (since XSLT has no actual loop constructs), and the contains(), 
substring-before(), and substring-after() functions will help.

The loop will need to alternate between two different states: (1) search for 
the "/*", and (2) search for the "*/".  When (1) is matched, the process will 
proceed using (2), and once (2) is matched, the process will repeat with (1).

<!-- the 'xsl:' prefix has been removed from all elements for brevity -->

<template name="format-comment">
  <param name="text"/>
  <!-- state (1): search for the "/*" -->
    <when test="not(contains($text, '/*'))">
      <!-- process complete; no more comments -->
      <value-of select="$data"/>
      <!-- output text before the comment start -->
      <value-of select="substring-before($text, '/*')"/> 
      <!-- ## output openning formatting tags ## -->
      <!-- search for closing '*/' -->
      <call-template name="format-comment-close">
        <!-- search in the remaining text following the '/*' -->
        <with-param name="text" select="substring-after($text, '/*')"/>

<template name="format-comment-close">
  <param name="text"/>
  <!-- state (2) -->
    <when test="not(contains($text, '*/'))">
      <!-- unclosed comment; it's up to you what to do here -->
      <value-of select="$text"/>
      <!-- output text before the comment end -->
      <value-of select="substring-before($text, '*/')"/>
      <!-- ## output closing formatting tags ## -->
      <!-- repeat search for openning '/*' -->
      <call-template name="format-comment">
        <!-- search in the remaining text following the '*/' -->
        <with-param name="text" select="substring-after($text, '*/')"/>


You may notice that the two templates share a lot of common structure; it 
should be possible to collapse the two into a single template by doing some 
tricks with <xsl:param/>, but I'll leave that up to you.  For clarity (and to 
save me time), I left it as two templates.

The biggest problem you will have with the above is with the HTML <div> tags 
you want to output surrounding the comment.  The openning "<div>" needs to be 
output in the first template, but the closing "</div>" needs to be output in 
the second template.  This is not easy with XSLT.

I can think of two ways to work around this:

(1) Output the openning and closing <div></div> with disable-output-escaping 
in order to avoid making the stylesheet well-formed XML:

<xsl:text disable-output-escaping="yes">&lt;div ...&gt;</xsl:text>
<xsl:text disable-output-escaping="yes">&lt;/div&gt;</xsl:text>

(2) Nest multiple <div> tags, switching back and forth between normal and 
"comment" formatting.  I recommend this option solely because of the problems 
inherent with d-o-e, but it can make the resulting HTML fairly ugly if the 
text has a lot of comments (each comment and the text following the comment 
will be nested successively deeper; the end of the text would be followed by 
a series of "</div></div></div>...", one for each comment).

To do this, where I say "output openning formatting tags" in the first 
template, you would surround the <call-template/> tag like this:

<div style="font-weight: bold; color: #494B95">
  <xsl:call-template name="format-comment-close">
    <xsl:with-param .../>

And you will surround the <call-template/> in the second template with another 
<div> with "inverse" CSS properties:

<div style="font-weight: normal; color: #000000">
  <xsl:call-template name="format-comment">
    <xsl:with-param .../>

Hopefully it is clear how this will work when it is all put together.  Hope 
that helps!

- -- 
Peter Davis
Version: GnuPG v1.0.7 (GNU/Linux)


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

Current Thread


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.
First Name
Last Name
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.