Preserving line breaks in xml while transforming to html with xslt
Posted by Dan Rigsby on 3rd January 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.
Posted in xslt | 11 Comments »
















