How do I preserve things like tabs and carriage returns in text? when transforming XML to XHTML with XSL. For example:

XML

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="article.xsl"?>
<content>
	<article name="Test Article">
		<heading>Test Article</heading>
		<subheading>Special Chars</subheading>
		<paragraph>
			<text>
				a less than &lt;
				a greater than &gt; 
			</text>
			<text type="code">
				some code.
			</text>
		</paragraph>
	</article>
</content>

XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="content">
	<xsl:apply-templates select="article" />
</xsl:template>

<xsl:template match="article">
	<h2><xsl:value-of select="heading" /></h2>
	<xsl:value-of select="subheading" />
	<xsl:for-each select="paragraph">
		<p>
		<xsl:for-each select="text">
		<xsl:choose>
			<xsl:when test="@type = 'link'">
				<a href="{@href}" target="{@target}">
				<xsl:value-of select="." />
				</a>
			</xsl:when>
			<xsl:when test="@type = 'code'">
				<div class="code">
				
				<xsl:value-of select="." />
				
				</div>
			</xsl:when>
			<xsl:otherwise>
				
				<xsl:value-of select="." />
				
			</xsl:otherwise>
		</xsl:choose>
		</xsl:for-each>
	</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

The carriage return between the text line:
a less than &lt;
And
a greater than &gt;

is lost when rendered in the browser, I sort of understand why that is, but I don't know how to apply XML or XSL to include/preserve or force the carriage return.

Dani AI

Generated

Short expert note: the symptom described (newlines present in the XML source but not visible in the rendered page) is usually the browser collapsing whitespace rather than XSLT throwing characters away. correctly noticed the client-side transformNode step — that can hide whether newlines survive the stylesheet or are lost when the output is inserted into the DOM. and are right that converting newlines to <br/> will force visible breaks, and 's whitespace pointer is on target — but there are cleaner options depending on goals (preserve formatting vs. convert to HTML breaks).

Practical options and tradeoffs

  • Preserve source whitespace and let the browser show it:

    <!-- in the stylesheet -->
    <xsl:preserve-space elements="text"/>
    /* in the generated HTML */
    .preserve { white-space: pre-line; } /* preserves line breaks but allows wrapping */

    Emit the text into a block that uses that CSS (or use <pre> for exact formatting). This is the simplest, most robust fix: it keeps author intent (newlines) and avoids fragile output-escaping tricks.

  • Convert newlines to HTML breaks (when the goal is inline text with explicit <br/>):

    <!-- XSLT 2.0 -->
    <xsl:value-of select="replace(., '&#xA;', '<br/>')" disable-output-escaping="yes"/>

    In XSLT 1.0 this requires a small recursive template to split on newline. Note: disable-output-escaping and some serializer tricks are processor-dependent and less reliable in client-side transforms.

Quick diagnostics (relevant when using client-side transformNode)

var out = xmlDoc.transformNode(xslDoc);
console.log(out);               // inspect whether '\n' chars remain in the serialized result
document.getElementById('out').innerHTML = out;

If out contains newlines but the page still shows them as a single wrapped line, the issue is HTML whitespace collapsing and the CSS/pre approach is the right fix. If out already lacks newlines, check for xsl:strip-space, normalize-space() calls, or processor-specific behavior in the transform step.

Summary: prefer xml:space="preserve" / <xsl:preserve-space/> + CSS (white-space: pre-line or pre-wrap) for predictable results; use newline-to-<br/> only when semantic HTML line breaks are required and accept the extra processing or XSLT-version constraints.

Recommended Answers

All 4 Replies

Is there a way to make substitutions? I know nothing of xslt, but you want to substitute a <br /> tag where ever the style sheet encounters the &gt;

If you are generating the xml yourself, you might try this:

<text>
  <table>
    <tr>
      <td>a less than</td>
      <td>a greater than</td>
    </tr>
  </table 
</text>

Hope this helps.. :sad:

Thanks guys.

I followed Daves links, it tells me XSL preserves whitespace by default. What I havn't mentioned is that in my particular scenario i'm using client javascript transformNode function and I can't be certain if that is doing what it should.

Anyway I have plenty of options to try now. If I nail it, i'll post the horrid details.

You need to replace the line carriage characters with <br/> tags.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.