RE: [xsl] Search and Replace Help

Subject: RE: [xsl] Search and Replace Help
From: cknell@xxxxxxxxxx
Date: Sun, 20 May 2007 09:59:29 -0400
It seems that the list is very quiet on the weekends.

First, "[quote=name]...[/quote]" is not XML. So it is unreasonable to expect to be able to use XSLT to do anything with them except reproduce it as is or operate on it with string methods.

You have a "message" element. It appears between the opening and closing (<message></message>) tags.

The entire content of the message element is enclosed in <![CDATA[]]>. This is an instruction to the XSLT processor to treat the enclosed bytes as text, not markup. As far as the stylesheet is concerned, there is no structure between <![CDATA[ and ]]>, it's just a collection of bytes.

There is some evidence that you are working in this way, but since you say that you are new to XSLT, and since it is a frequent error by newcomers to assume that because they see a structure inside the <![CDATA[]]> tag, that the XSLT processor must therefore also see it.

So, on to your specific complaints.
==========================
1) it is writing out/displaying <br /> instead
of doing a line break

You are getting a break element (<br/>) because that's what you told the stylesheet to output:
e.g.,
<xsl:text>To: </xsl:text> <xsl:value-of select="touser"/><br />

What constitutes a "line break" depends on what your platform is. In an HTML browser, the "<br/>" element is a line break. In Windows, you need a carriage return character and a linefeed character. In Linux/Unix you need only the linefeed, on the Mac OS (up to version 9), it was only the carriage return.

If you could identify what your target is (apparently not an HTML browser) you could instruct the XSLT processor to output the ASCII character or characters to produce a newline by inserting that/those characters in the stylesheet where you now have the <br/> element. 

The linefeed is & #10; and the carriage return is & #13; (I've inserted a space between the ampersand and the # to prevent any possible literal interpretation by your mail reader as instructions. When you use them in your stylesheet, be sure that no space appears there.

2) I need to replace [QUOTE=jack] & [QUOTE=john]
with <blockquote><i>Originally posted by: <b>jack (or john)</b></i> (while
allowing for the fact that there may be a mary, jake, etc.) and [/QUOTE]
with </blockquote>.

As I said earlier, this is not XML markup and XSLT templates won't process them as if it were. If you are using an XSLT 2.0 processor, you could use the regex functions to process this string data and create the elements. Alternatively, you could use Java or perl or C# or C or VB (well, you get the idea) to create a pre-processor that would create the elements before you fed it into the stylesheet.


-- 
Charles Knell
cknell@xxxxxxxxxx - email



-----Original Message-----
From:     Matthew Ebbertt <mje004@xxxxxxxx>
Sent:     Sat, 19 May 2007 14:28:32 -0400
To:       <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject:  [xsl] Search and Replace Help

I'm new (as in just started working on it last night) to the whole XML and
XSL thing.  What I am trying to do relates to the popular vBulletin message
boards where you can download private messages in XML format.  I've created
an XSL that transforms the XML into something infinitely more readable, but
I've run into a snag trying to do a search and replace.  As shown below,
there are tags that get exported of the form [quote=name]...[/quote].  What
I'm trying to do is replace every instance of that with XHTML code that goes
<blockquote><i>Originally posted by: <b>name</b></i>...</blockquote>.  I've
tried using the script posted at
http://topxml.com/snippetcentral/main.asp?view=viewsnippet&lang=xsl&id=v2001
0223112713 but even that won't work in the example he used (it simply writes
out <br /> and displays that, instead of it doing a line feed as the <br />
tag is supposed to do).  I haven't even tried to manipulate it more after I
ran into that problem.  I have no experience with any programming, just good
old HTML type stuff, so this is all new territory for me.  Here are examples
of what I'm working with.

The XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="pms.xsl"?>

<privatemessages>
    <folder name="Sent Items">
        <privatemessage>
            <datestamp>2007-02-14 09:09</datestamp>
            <title>Re: Heroes</title>
            <fromuser>jack</fromuser>
            <fromuserid>112</fromuserid>
            <touser>john</touser>
            <message><![CDATA[[QUOTE=jack][QUOTE=john]How you
doing?[/QUOTE]

Good.  You?[/QUOTE]

Cool.]]></message>
        </privatemessage>
    </folder>
</privatemessages>

The XSL (pms.xsl)
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="html"/>
 
 <xsl:template match="/">

<html xmlns="http://www.w3.org/1999/xhtml";>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<style type="text/css">
blockquote {border: thin solid black;}
body {background-color: #DCDCDC;font-family: Arial, Helvetica,
sans-serif;font-size: 12px;color: #336699;}
td, th {font-family: Arial, Helvetica, sans-serif;font-size:
12px;line-height: 24px;color: #333333;}
a {color: #3366CC;text-decoration: none;}
a:hover {text-decoration: underline;}
a:link {color: #0000FF;}
a:visited {color: #3366FF;}
a:hover {text-decoration: none;}
a:active {color: #FF0000;}
hr {border: 0; width: 90%; height: 2px; background-color: #000000; color:
#000000;}
TABLE {width: 100%; border:thin solid black; border-collapse:collapse;
empty-cells:hide;}
TD {border: thin solid black;}
</style>
<title><xsl:for-each select="privatemessages/folder"><xsl:value-of
select="@name" /></xsl:for-each></title>
</head>
<body>
<xsl:for-each select="privatemessages/folder/privatemessage">
    <xsl:text>From: </xsl:text><a
href="http://www.website.com/vb/member.php?u={fromuserid}";><xsl:value-of
select="fromuser"/></a><br />
    <xsl:text>To: </xsl:text> <xsl:value-of select="touser"/><br />
    <xsl:text>On: </xsl:text> <xsl:value-of select="datestamp"/><br />
    <xsl:text>Subject: </xsl:text> <xsl:value-of select="title"/><br />
    <table>
    <tr>
    <td valign="top" width="60px" style="text-align:
center;"><xsl:text>Message:</xsl:text></td>
    <td>
    <xsl:call-template name="replace-text">
      <xsl:with-param name="text" select="message"/>
      <xsl:with-param name="replace" select="'
'"/>
      <xsl:with-param name="by" select="'<br />'"/>
    </xsl:call-template>
    </td>
    </tr>
    </table>
    <hr size="4" />
</xsl:for-each>
</body>
</html>

</xsl:template>
<!-- template that does a search & replace -->
<xsl:template name="replace-text">
   <xsl:param name="text"/>
   <xsl:param name="replace" />
   <xsl:param name="by"  />

   <xsl:choose>
   <xsl:when test="contains($text, $replace)">
      <xsl:value-of select="substring-before($text, $replace)"/>
      <xsl:value-of select="$by" disable-output-escaping="yes"/>
      <xsl:call-template name="replace-text">
         <xsl:with-param name="text" select="substring-after($text,
$replace)"/>
         <xsl:with-param name="replace" select="$replace" />
         <xsl:with-param name="by" select="$by" />
      </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
      <xsl:value-of select="$text"/>
   </xsl:otherwise>
   </xsl:choose>

</xsl:template>
</xsl:stylesheet>

The output (just the problem area):
[QUOTE=jack][QUOTE=john]How you doing?[/QUOTE]<br /><br />Good.
You?[/QUOTE]<br /><br />Cool.

So the two problems are that 1) it is writing out/displaying <br /> instead
of doing a line break and 2) I need to replace [QUOTE=jack] & [QUOTE=john]
with <blockquote><i>Originally posted by: <b>jack (or john)</b></i> (while
allowing for the fact that there may be a mary, jake, etc.) and [/QUOTE]
with </blockquote>.

Any ideas?

Current Thread