This problem is caused by the fact that text nodes with a space are also considered.
Decision
Include this global (best place before any <xsl:template> ) directive :
<xsl:strip-space elements="*"/>
This instructs the XSLT processor to separate only node text files from just the white space of any (*) element in the XML document.
So, your fixed conversion is now :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <xsl:for-each select="//*[text()]"> <xsl:if test="text()"> <Match> <xsl:value-of select="name()"/>: <xsl:value-of select="string-length(text())"/> </Match> <br /> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
and when applied to the provided XML document :
<BusinessLetter> <Head> <SendDate>November 29, 2005</SendDate> <Recipient> <Name Title="Mr."> <FirstName>Joshua</FirstName> <LastName>Lockwood</LastName> </Name> <Company>Lockwood & Lockwood</Company> <Address> <Street>291 Broadway Ave.</Street> <City>New York</City> <State>NY</State> <Zip>10007</Zip> <Country>United States</Country> </Address> </Recipient> </Head> </BusinessLetter>
required, the correct result is obtained :
<Match>SendDate: 17 </Match><br><Match>FirstName: 6 </Match><br><Match>LastName: 8 </Match><br><Match>Company: 19 </Match><br><Match>Street: 17 </Match><br><Match>City: 8 </Match><br><Match>State: 2 </Match><br><Match>Zip: 5 </Match><br><Match>Country: 13 </Match><br>
source share