Search code examples
xmlcountxslt-1.0contains

How to use contains() function to check in strings the presence of predefined substrings and count() the strings that match?


I'm trying to check in strings the presence of predefined substrings and then want to count() the elements that match these formats.

My example follows:

<!-- xslt code snippet; this is what I did, but I don't know
     how to count() them, I'm getting something like 111 as output :|
-->
<xsl:for-each select="automobile">
    <xsl:if test="contains(name_and_class, 'J.TK') or
        contains(name_and_class, 'P.LO') or contains(name_and_class, 'M.GA')">
        <xsl:value-of select="name_and_class"/>
 <!-- how can I count() them here-->
 
 <!-- xml code snippet -->
<automobile>
<name_and_class>Mercedes B.OO</name_and_class>
</automobile>
<automobile>
<name_and_class>Hummer P.LO</name_and_class>
</automobile>
<automobile>
<name_and_class>Audi J.TK</name_and_class>
</automobile>
<automobile>
<name_and_class>Ferrari M.GA</name_and_class>
</automobile>
<automobile>
<name_and_class>Mercedes F.BQ</name_and_class>
</automobile>

Solution

  • You can use predicate (expression in []) to filter elements, for example assuming that we have the following well-formed XML as input :

    <root>
        <automobile>
        <name_and_class>Mercedes B.OO</name_and_class>
        </automobile>
        <automobile>
        <name_and_class>Hummer P.LO</name_and_class>
        </automobile>
        <automobile>
        <name_and_class>Audi J.TK</name_and_class>
        </automobile>
        <automobile>
        <name_and_class>Ferrari M.GA</name_and_class>
        </automobile>
        <automobile>
        <name_and_class>Mercedes F.BQ</name_and_class>
        </automobile>
    </root>
    

    this template will output count of name_and_class elements that match the criteria without using xsl:for-each :

    <xsl:template match="/root">
        <xsl:value-of select="count(automobile[
            contains(name_and_class, 'J.TK') or
            contains(name_and_class, 'P.LO') or 
            contains(name_and_class, 'M.GA')
            ])"/>
    </xsl:template>
    

    xsltransform demo

    output :

    3