Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

count the number of occurrences of a string in XML using XSLT

Tags:

xml

count

xslt

I want to calcutae the number of occurrences of a string in a particular node in XML document using XSLT. Consider this example

 <mainNode>
<book>
    <price> 100 </price>
    <city> chennai </city>
    <list>
        <language> c java ruby </language>
    </list>
</book>

<book>
    <price> 200 </price>
    <city> banglore </city>
    <list>
        <language> c java </language>
    </list>
</book>

<book>
    <price> 300 </price>
    <city> delhi </city>
    <list>
        <language> java ruby </language>
    </list>
</book>
</mainNode>      

Here I want to count the occurrences of "java"

I Want Output like this:: java -- 3

How to do this??? any idea???

like image 679
Sathish Avatar asked Jul 13 '11 13:07

Sathish


People also ask

How do I count records in XSLT?

The syntax says the count function tells the XSLT processor to count each time in which an XML tag found at the XPATH expression. It returns a number value that specifies the number of sequence elements contained in a sequence of items that passes by. The empty set of the count is returned to 'zero'.

How do I count characters in XSLT?

To find out the number of characters in text, you can use the "string-length" function. Where 'propertyAlias' is the name of your property.

How do you set a counter in XSLT?

XSLT is a functional language, not a procedural language, so you can't declare a counter. You can use xsl:number to get the position of the current node in its parent, if that helps. You can coerce a string to a number by using the XPath number() function.

What is number () in XSLT?

Definition and Usage. The <xsl:number> element is used to determine the integer position of the current node in the source. It is also used to format a number.


1 Answers

Use:

count(/*/*/list/language[contains(., 'java')])

The complete XSLT transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
     java -- <xsl:value-of select=
       "count(/*/*/list/language[contains(., 'java')]) "/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<mainNode>
    <book>
        <price> 100 </price>
        <city> chennai </city>
        <list>
            <language> c java ruby </language>
        </list>
    </book>
    <book>
        <price> 200 </price>
        <city> banglore </city>
        <list>
            <language> c java </language>
        </list>
    </book>
    <book>
        <price> 300 </price>
        <city> delhi </city>
        <list>
            <language> java ruby </language>
        </list>
    </book>
</mainNode>

the wanted, correct result is produced:

 java -- 3

Update:

If we are to count all occurences of the string -- not just all nodes that contain the string -- here's how to do it:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"/>
    <xsl:param name="pWord" select="' java '"/>

    <xsl:template match="/">
        <xsl:variable name="vResult">
            <xsl:apply-templates/>
        </xsl:variable>
        <xsl:value-of select="concat($pWord, '--- ')"/>
        <xsl:value-of select="string-length($vResult)"/>
    </xsl:template>

    <xsl:template match="list/language" name="countWord">
        <xsl:param name="pText" select="."/>

        <xsl:if test="contains($pText, $pWord)">
            <xsl:text>X</xsl:text>
            <xsl:call-template name="countWord">
                <xsl:with-param name="pText"
                 select="concat(' ', substring-after($pText, $pWord))"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <xsl:template match="text()"/>
</xsl:stylesheet>

when this transformation is applied on this XML document:

<mainNode>
    <book>
        <price> 100 </price>
        <city> chennai </city>
        <list>
            <language> c java ruby </language>
        </list>
    </book>
    <book>
        <price> 200 </price>
        <city> banglore </city>
        <list>
            <language> c java </language>
        </list>
    </book>
    <book>
        <price> 300 </price>
        <city> delhi </city>
        <list>
            <language> java java ruby </language>
        </list>
    </book>
</mainNode>

the wanted, correct result is produced:

 java --- 4
like image 83
Dimitre Novatchev Avatar answered Sep 22 '22 14:09

Dimitre Novatchev