Arpit Khandelwal
Arpit Khandelwal

Reputation: 1803

Count number of lines in XSLT

When transforming this XML, I need to count the number of line breaks in this XML node

    <SpecialInstraction>One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
twelve
thirteen
fourteen
fifteen</SpecialInstraction>

Like above example have 14 line breaks.

I tried to determine the number of occurrences of "&#xD;&#xA;" and "&#13;" but even if there is no change in above XML, the number of occurrences keep varying everytime this XML goes under serialization/deserialization.

Anybody has any ideas how I can get the count of lines from value of an XML node in XSLT?

Upvotes: 1

Views: 3328

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243469

Use:

string-length() - string-length(translate(., '&#xA;', ''))

Although by using the above XPath one-liner, you don't need XSLT at all, for comleteness here is it:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="text()">
     <xsl:value-of select=
     "string-length() - string-length(translate(., '&#xA;', ''))"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<SpecialInstraction>One
    Two
    Three
    Four
    Five
    Six
    Seven
    Eight
    Nine
    Ten
    Eleven
    twelve
    thirteen
    fourteen
    fifteen</SpecialInstraction>

the wanted, correct result is produced:

14

Do note:

This solution onlu counts the number of NL characters. Why did I ignore the CRs? Simply because according to the W3C XML Specification, any compliant XML parser must do the following:

all #xD characters literally present in an XML document are either removed or replaced by #xA characters before any other processing is done.

Upvotes: 1

nyxthulhu
nyxthulhu

Reputation: 9752

There was a similar question on StackOverflow - (count the number of words in a xml node using xsl) for counting the number of spaces in a string. I've adapted the code a little stolen from there to use newlines.

<xsl:template name="word-count">
        <xsl:param name="data"/>
        <xsl:param name="num"/>
        <xsl:variable name="newdata" select="$data"/>
        <xsl:variable name="remaining" select="substring-after($newdata,'&#10;')"/>                

        <xsl:choose>
                <xsl:when test="$remaining">
                        <xsl:call-template name="word-count">
                                <xsl:with-param name="data" select="$remaining"/>
                                <xsl:with-param name="num" select="$num+1"/>
                        </xsl:call-template>
                </xsl:when>
                <xsl:when test="$num = 1">
                        no words...
                </xsl:when>
                <xsl:otherwise>
                        <xsl:value-of select="$num"/>
                </xsl:otherwise>
        </xsl:choose>                
</xsl:template>

Upvotes: 0

Related Questions