Controlling Whitespace, Part Two
by Bob DuCharme
|
Pages: 1, 2
Normalizing Space
|
Also in Transforming XML | |
Imagine that your source document has extra whitespace in places, but not consistently, and you want to get rid of this whitespace to make it consistent. For example, the first employee element in the following has no extra spaces or carriage returns within its child elements, but the second one has plenty.
<employees> <employee hireDate="09/01/1998"> <last>Herbert</last> <first>Johnny</first> <salary>95000</salary> </employee> <employee hireDate=" 04/23/1999"> <last> Hill </last> <first> Phil </first> <salary>100000 </salary> </employee> </employees>
A simple stylesheet to create comma-delimited versions of each employee's data, like this,
<!-- xq546.xsl: converts xq543.xml into xq548.txt --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" omit-xml-declaration="yes"/> <xsl:template match="employee"> <xsl:apply-templates select="@hireDate"/> <xsl:text>,</xsl:text> <xsl:apply-templates select="first"/> <xsl:text>,</xsl:text> <xsl:apply-templates select="last"/> </xsl:template> </xsl:stylesheet>creates output that includes all that extra whitespace:
09/01/1998,Johnny,Herbert 04/23/1999, Phil , Hill
The normalize-space() function, in addition to converting strings of multiple space characters into a single space, deletes any leading and trailing spaces from the string passed to it as an argument. Using it can solve the problem with the stylesheet above:
<!-- xq544.xsl: converts xq543.xml into xq547.txt --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" omit-xml-declaration="yes"/> <xsl:template match="employee"> <xsl:value-of select="normalize-space(@hireDate)"/> <xsl:text>,</xsl:text> <xsl:value-of select="normalize-space(first)"/> <xsl:text>,</xsl:text> <xsl:value-of select="normalize-space(last)"/> <!-- Following alternative won't work: <xsl:apply-templates select="normalize-space(@hireDate)"/> <xsl:text>,</xsl:text> <xsl:apply-templates select="normalize-space(first)"/> <xsl:text>,</xsl:text> <xsl:apply-templates select="normalize-space(last)"/> --> </xsl:template> </xsl:stylesheet>
Note the comment in the second half of the "employee" template rule. We can't just insert the normalize-space() function inside the select attributes of the previous stylesheet's xsl:apply-templates instructions, because this function returns a string and xsl:apply-templates expects to see a node set expression as the value of its select attribute. So, the template uses xsl:value-of instructions instead, the normalize-space() function works, and the result is formatted consistently:
09/01/1998,Johnny,Herbert 04/23/1999,Phil,Hill
In next month's final installment of this series on controlling whitespace, we'll look at how an XSLT stylesheet can add tabs to your result document and a built-in feature that automates intelligent indenting of your result documents.
- Preserving whitespace
2009-04-09 14:18:08 shark59 - Works like a charm
2004-11-23 12:50:32 WildBlue27 - I get a space instead of a line break
2002-02-12 12:47:07 Meili Huang - Sample problem
2002-02-11 07:12:07 Antonio del Pozzo - Sample problem
2002-02-13 14:00:33 Bob DuCharme - CDATA
2001-12-07 19:21:19 Jay Singh - CDATA
2002-02-13 14:06:19 Bob DuCharme