Preserving line breaks in xml while transforming to html with xslt
Posted by Dan Rigsby on January 3rd, 2008
When using xslt to transform xml into html, sometimes it may be desired to keep the line breaks in the text of the xml and convert them into <br/> tags. For instance, we pipe the output of build and database scripts to xml. When rendering into html, we want to keep the line breaks or the text looks garbled. There are many other situations where you might want to preserve line breaks, but bare with me.
Below I have some text copied from an execution of msbuild. This text is stored directly into a <text> node in the xml:
<text>Microsoft (R) Build Engine Version 3.5.21022.8 [Microsoft .NET Framework, Version 2.0.50727.1433] Copyright (C) Microsoft Corporation 2007. All rights reserved. Build started 1/2/2008 6:34:50 PM. Done Building Project "D:\builds\ININ.BCF.sln" (default targets). Build succeeded. 0 Warning(s) 0 Error(s)</text>
A simple xslt to convert this into html might look like this:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:value-of select="/text"/> </xsl:template> </xsl:stylesheet>
The problem with the xslt is that the line breaks aren’t preserved and as a result, the text looks garbled:
Microsoft (R) Build Engine Version 3.5.21022.8 [Microsoft .NET Framework, Version 2.0.50727.1433] Copyright (C) Microsoft Corporation 2007. All rights reserved. Build started 1/2/2008 6:34:50 PM. Done Building Project "D:\builds\ININ.BCF.sln" (default targets). Build succeeded. 0 Warning(s) 0 Error(s)
Here is the same xslt with the inclusion of a PreserveLineBreaks template:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict"> <xsl:output method="html"/> <xsl:template match="/"> <xsl:call-template name="PreserveLineBreaks"> <xsl:with-param name="text" select="/text"/> </xsl:call-template> </xsl:template> <xsl:template name="PreserveLineBreaks"> <xsl:param name="text"/> <xsl:choose> <xsl:when test="contains($text,'
')"> <xsl:value-of select="substring-before($text,'
')"/> <br/> <xsl:call-template name="PreserveLineBreaks"> <xsl:with-param name="text"> <xsl:value-of select="substring-after($text,'
')"/> </xsl:with-param> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
The template preserves line breaks by writing out the text before the line break, adding a <br/> tag, then recursively calling the template again to look for addition line breaks in the remaining text. This process continues until every line break is essentially replaced with a <br/>.
Microsoft (R) Build Engine Version 3.5.21022.8
[Microsoft .NET Framework, Version 2.0.50727.1433]Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 1/2/2008 6:34:50 PM.
Done Building Project "D:\builds\ININ.BCF.sln" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
This template could even be modified to replace other characters such as tabs depending on your needs.

















April 28th, 2008 at 2:02 am
Thank you soooo much. This really saved my day.
May 5th, 2008 at 11:07 am
Thanks for the article. The XSL Template worked out nicely for my task.
May 6th, 2008 at 9:33 am
Thanks a mil for this!
December 22nd, 2008 at 3:53 am
Thanx a lot! It really helped me out!
February 13th, 2009 at 10:14 am
Thanks Dan, I’d been looking for a solution to this for ages. It works a treat!
March 20th, 2009 at 10:58 am
Thanks a lot, this is exactly what I was looking for.
The only thing I would change in the example is to use slightly different names for the text node and the template’s parameter, because it might take some people (ok, me) a few extra seconds to understand name=”text” select=”/text”.
Thanks again.
March 26th, 2009 at 7:16 pm
Thanks a heap Dan, that problem with xslt had been annoying me all morning! Worked great!
May 26th, 2009 at 6:50 pm
great example! i spent all day trying to get line breaks from my xml to show up using xsl! thank you!
July 9th, 2009 at 5:48 am
Another option is to preserve the formatting using the html tag.
e.g.
January 21st, 2010 at 3:02 pm
Thank you so much Dan… You save me
February 18th, 2010 at 4:54 am
Is it possible to use a similar method to preserve line breaks when output method is ‘text’?
I have some formatted XML that I am trying to transform to text, but it will not preserve the line breaks in the text output.