Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 30th, 2008, 01:58 PM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 2
Thanked 0 Times in 0 Posts
Default replace function for line breaks

Hi Guys,

your gonna have to bear with me on this, I'm probably not gonna explain myself very well..

here goes..

I am trying to write a little routine that replace a special character in a string with a html line break.

here is my attempt..

Code:
    <xsl:template name="linebreak">
        <br />
    </xsl:template>

    <xsl:template name="replaceNewLines">
        <xsl:param name="stringIn" />
        <xsl:param name="break" />
        <xsl:choose>
            <xsl:when test="contains($stringIn,'/nl')">
                <xsl:value-of select="concat(substring-before($stringIn,'/nl'),$break)" />
                <xsl:call-template name="replaceNewLines">
                    <xsl:with-param name="stringIn" select="substring-after($stringIn,'/nl')" />
                    <xsl:with-param name="break">
                        <xsl:call-template name="linebreak" />
                    </xsl:with-param>    
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$stringIn" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
and here is where I try and call it..

Code:
<p>                                
    <xsl:call-template name="replaceNewLines">
        <xsl:with-param name="stringIn" select="/client/dataItems/dataItem[name='DP.CustomParagraph']/amount"/>
        <xsl:with-param name="break">
            <xsl:call-template name="linebreak" />
        </xsl:with-param>
    </xsl:call-template>
</p>
in my xml I have DP.CustomParagraph which contains /nl I want replace that with <br />.

it nearly works, if in my new line template I change <br /> with 'hello' it works, it just doesn't seem to spit out any HTML??

please help..

I have a project waiting for me to fix this before it goes into UAT so I'm under a bit of pressure..:(

 
Old August 31st, 2008, 04:43 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Your code looks OK but the way you are calling it seems odd. What is the context node at the point you call it? How are you using the result of the call?

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old August 31st, 2008, 02:54 PM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Cheers Mike,

I'm not sure I've understood your reply too well (XSL is not my strong point at all)...

By context node do you mean what is in the value of 'DP.CustomParagraph'??

this can be anything a user enters in a free text box, this is then saved to a SQL database I then pull it back from the DB through a stored Proc as XML and replace the carriage returns char(13) with '/nl'

so for example the DP.CustomParagraph node could contain ..

hello./nlThis is a line break test.

I am trying to use the result in a HTML <p> tag.

so the above context would transform as...

<p>
   hello<br />This is a line break test.
</p>

Hope I have understood you correct and this clears things up a little.

cheers

Daz

 
Old August 31st, 2008, 05:15 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Oh dear, this doesn't sound good at all. Your project is under time pressure, you're trying to get XSLT code working, but you don't yet know what a "context node" is. Your first action should be to tell your project manager that there is a problem and that you probably aren't going to achieve your deadlines.

What my reply meant is that the template "replaceNewLines" looks OK but I suspect you are either calling it with the wrong parameters, or you are using the result incorrectly. I can't be sure of that without seeing your source document and more of the stylesheet. The parameter value select="/client/dataItems/dataItem[name='DP.CustomParagraph']/amount looks highly suspicious: I strongly suspect, though you haven't shown a source document, that this expression selects many <amount> elements and you want to apply the template to each one of them, whereas the way you are doing it you are only applying it to the first.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old September 1st, 2008, 03:29 AM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 2
Thanked 0 Times in 0 Posts
Default

"Oh dear, this doesn't sound good at all" - Tell me about it..

I really know very little about XSL, the person who started this and decided that XSL was what we needed to do this has gone on holiday, the project has now gone into UAT with this bug in and the pressure is on me to fix it :(

I have done a very stripped down version I can give you so you can see exactly what I've got, but I'm not sure you can add attachments so I will give you all the code here.. (there's not much...)

first file is an HTML transform file so I can view my transformed output.

Transform.htm
Code:
<html>
<head>
</head>     
<body>
    <script type="text/javascript">
    var xml = new ActiveXObject("Microsoft.XMLDOM")
    xml.async = false
    xml.load("test1.xml")
    var xsl = new ActiveXObject("Microsoft.XMLDOM")
    xsl.async = false
    xsl.load("test1.xsl")
    document.write(xml.transformNode(xsl))
</script>
</body>
</html>
then the XML file
test1.xml
Code:
<client>
    <dataItems>
    <dataItem>
      <name>DP.Name</name>
      <amount>Darren</amount>
    </dataItem>        
        <dataItem>
            <name>DP.CustomParagraph</name>
            <amount>sdfdsf/nl/nlsfdsdf</amount>
        </dataItem>
    </dataItems>
</client>
then the XSL file
test1.xsl
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/client">

        <p><xsl:value-of select="/client/dataItems/dataItem[name='DP.Name']/amount"/> Wrote:</p>
        <p>
            <xsl:call-template name="replaceNewLines">
                <xsl:with-param name="stringIn" select="/client/dataItems/dataItem[name='DP.CustomParagraph']/amount"/>
                <xsl:with-param name="break">
                    <xsl:call-template name="linebreak" />
                </xsl:with-param>
            </xsl:call-template>                                
        </p>
    </xsl:template>    


    <xsl:template name="linebreak">
        <br />
    </xsl:template>

    <xsl:template name="replaceNewLines">
        <xsl:param name="stringIn" />
        <xsl:param name="break" />
        <xsl:choose>
            <xsl:when test="contains($stringIn,'/nl')">
                <xsl:value-of select="concat(substring-before($stringIn,'/nl'),$break)" />
                <xsl:call-template name="replaceNewLines">
                    <xsl:with-param name="stringIn" select="substring-after($stringIn,'/nl')" />
                    <xsl:with-param name="break">
                        <xsl:call-template name="linebreak" />
                    </xsl:with-param>    
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$stringIn" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet
by creating these 3 files and running Transform.htm, you will be able to see what I'm trying to do, and what problem I'm having.

Again Cheers
Daz

 
Old September 1st, 2008, 03:48 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Actually it is the template that's wrong - I missed the error.

<xsl:value-of select="concat(substring-before($stringIn,'/nl'),$break)" />

This converts the value of $break to a string. $break is a <br/> element, and when you convert an element to a string, it takes the content of the element, which is empty. You want

<xsl:value-of select="substring-before($stringIn,'/nl')" />
<xsl:copy-of select="$break"/>

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old September 1st, 2008, 03:53 AM
Authorized User
 
Join Date: Jun 2006
Posts: 22
Thanks: 2
Thanked 0 Times in 0 Posts
Default

You my friend are a genius and a life saver..

many many many thanks :D






Similar Threads
Thread Thread Starter Forum Replies Last Post
line breaks mister_mister XSLT 14 March 17th, 2008 12:55 PM
How to do line breaks! Apocolypse2005 Beginning VB 6 2 December 11th, 2006 03:20 PM
Want to detect line breaks conundrum Classic ASP Basics 1 October 3rd, 2003 04:05 AM
problems with line breaks sanchezal XSLT 7 July 30th, 2003 03:09 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.