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

I want to calculate the number of occurrences of a string in a specific node in an 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 the result to be as follows: java - 3

How to do it??? any idea ???

+5
source share
4 answers

Using

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

Full XSLT conversion :

<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 to 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>

required, the correct result is obtained :

 java -- 3

Update

If we count all the occurrences of the string, and not just all the nodes containing 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>

, XML-:

<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>

, :

 java --- 4
+6

, XSL Template :

<xsl:template name="substring-count">
  <xsl:param name="string"/>
  <xsl:param name="substr"/>
  <xsl:choose>
    <xsl:when test="contains($string, $substr) and $string and $substr">
      <xsl:variable name="rest">
        <xsl:call-template name="substring-count">
          <xsl:with-param name="string" select="substring-after($string, $substr)"/>
          <xsl:with-param name="substr" select="$substr"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:value-of select="$rest + 1"/>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

:

<xsl:call-template name="substring-count">
  <xsl:with-param name"string" select="'mary had a little lamb'" />
  <xsl:with-param name="substr" select="'lamb'" />
</xsl:call-template>
+1

<xsl:value-of>:

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

, language , , //language /mainNode/book/list/language.

concat , , , , , ' java ' , ' t , java, javascript.

, "java" node, . :

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:template match="/">
    <xsl:variable name="list">
      <xsl:for-each select="//language">
        <xsl:call-template name="count">
          <xsl:with-param name="lang">java</xsl:with-param>
        </xsl:call-template>
      </xsl:for-each>
    </xsl:variable>
    <xsl:value-of select="concat('java -- ',string-length($list))" />
  </xsl:template>

  <xsl:template name="count">
    <xsl:param name="lang" />
    <xsl:param name="text" select="text()" />
    <xsl:if test="contains(concat(' ',$text,' '),concat(' ',$lang,' '))">
      <xsl:text>0</xsl:text>
      <xsl:call-template name="count">
        <xsl:with-param name="lang" select="$lang" />
        <xsl:with-param name="text" select="substring-after($text,$lang)" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

0 's, java, .

XSLT 2.0, , <xsl:value-of select="sum(mycountfunction(//language))" /> - .

, XML ; , . , , ( ), .

+1

All Articles