23
votes

I want to implement carriage return within xslt. The problem is I have a varible: Step 1 = Value 1 breaktag Step 2 = Value 2 as a string and would like to appear as

Step 1 = Value 1

Step 2 = Value 2

in the HTML form but I am getting the br tag on the page.Any good ways of implementing a line feed/carriage return in xsl would be appreciated

10

10 Answers

45
votes

As an alternative to

<xsl:text>
</xsl:text>

you could use

<xsl:text>&#10;</xsl:text> <!-- newline character -->

or

<xsl:text>&#13;</xsl:text> <!-- carriage return character -->

in case you don't want to mess up your indentation

9
votes

This works for me, as carriage-return + life feed.

<xsl:text>&#xD;&#xA;</xsl:text>

The "&#10;" string does not work.

4
votes

use a simple carriage return in a xsl:text element

<xsl:text>
</xsl:text>
3
votes

Try this at the end of the line where you want the carriage return. It worked for me.

<xsl:text><![CDATA[<br />]]></xsl:text>
3
votes

I was looking for a nice solution to this, as many would prefer, without embedding escape sequences directly in the expressions, or having weird line breaks inside of a variable. I found a hybrid of both this approaches actually works, by embedding a text node inside a variable like this:

<xsl:variable name="newline"><xsl:text>&#10;</xsl:text></xsl:variable>
<xsl:value select="concat(some_element, $newline)" />

Another nice side-affect of this is that you can pass in whatever newline you want, be it just LF, CR, or both CRLF.

--Daniel

3
votes

The cleanest way I've found is to insert !ENTITY declarations at the top of the stylesheet for newline, tab, and other common text constructs. When having to insert a slew of formatting elements into your output this makes the transform sheet look much cleaner.

For example:

<?xml version="1.0"?>
<!DOCTYPE xsl:stylesheet [
    <!ENTITY nl "<xsl:text>
</xsl:text>">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="step">
    &nl;&nl;
    <xsl:apply-templates  />
  </xsl:template>

...

1
votes

Here is an approach that uses a recursive template, which looks for &#10; in the string from the database and then outputs the substring before. If there is a substring after &#10; remaining, then the template calls itself until there is nothing left. In case &#10; is not present then the text is simply output.

Here is the template call (just replace @ActivityExtDescription with your database field):

<xsl:call-template name="MultilineTextOutput">
    <xsl:with-param name="text" select="@ActivityExtDescription" />
</xsl:call-template>

and here is the code for the template itself:

<xsl:template name="MultilineTextOutput">
<xsl:param name="text"/>
<xsl:choose>
    <xsl:when test="contains($text, '&#10;')">
        <xsl:variable name="text-before-first-break">
            <xsl:value-of select="substring-before($text, '&#10;')" />
        </xsl:variable>
        <xsl:variable name="text-after-first-break">
            <xsl:value-of select="substring-after($text, '&#10;')" />
        </xsl:variable>

        <xsl:if test="not($text-before-first-break = '')">
            <xsl:value-of select="$text-before-first-break" /><br />
        </xsl:if>

        <xsl:if test="not($text-after-first-break = '')">
            <xsl:call-template name="MultilineTextOutput">
                <xsl:with-param name="text" select="$text-after-first-break" />
            </xsl:call-template>
        </xsl:if>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$text" /><br />
    </xsl:otherwise>
</xsl:choose>

Works like a charm!!!

0
votes

I believe that you can use the xsl:text tag for this, as in

<xsl:text>
</xsl:text>

Chances are that by putting the closing tag on a line of its own, the newline is part of the literal text and outputted as such.

0
votes

I separated the values by Environment.NewLine and then used a pre tag in html to emulate the effect I was looking for

0
votes

This is the only solution that worked for me. Except I was replacing &#10; with \r\n