uner
uner

Reputation: 131

XSLT: count number of occurrences for each regexp match

I have an XML file with sentences tagged as and I want to list sentences matched against a regexp and a count of how many times a sentence was matched for that particular string.

Now for a regexp stored in $search I have:

<table border="1">
    <xsl:apply-templates select="//s[matches(., $search)]"/>
</table>

<xsl:template match="s">
    <tr>
        <xsl:analyze-string select="." regex="{$search}">
                <xsl:matching-substring>
                    <td><xsl:value-of select="regex-group(1)"/></td>                     
                    <xsl:value-of select="count(//s[matches(., regex-group(1))])"/>
                </xsl:matching-substring>
                <xsl:non-matching-substring>
                    <td><xsl:value-of select="."/></td>
                </xsl:non-matching-substring>
            </xsl:analyze-string>        
    </tr>
</xsl:template>

The count() line throws an error: "Leading '/' cannot select the root node of the tree containing the context item: the context item is not a node".

How can I count all sentences that matched my regexp $search?

EDIT: To elucidate, let's say my regexp is 'colou?rs' and the XML is:

<s>I like colors.</s> <s>colours are nice.</s> <s>there are two colors.</s> 

I want something like:

I like colors. - 2 
colours are nice. - 1 
there are two colors. - 2

Upvotes: 0

Views: 437

Answers (1)

Marjorie
Marjorie

Reputation: 71

You just need to declare this global variable to access your document root from anywhere:

<xsl:variable name="docRoot" select="/"/>

Then do something like this:

<xsl:template match="s">
    <tr>            
        <xsl:analyze-string select="." regex="{$search}">                
            <xsl:matching-substring>
                <xsl:variable name="myMatch"><xsl:value-of select="regex-group(1)"/></xsl:variable>
                <td><xsl:value-of select="regex-group(1)"/>
                <xsl:text> (</xsl:text>
                    <xsl:value-of select="count($docRoot//s[matches(., $myMatch)])"/>
                <xsl:text> occurrences)</xsl:text>   
                </td>                                                             
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <td><xsl:value-of select="."/></td>
            </xsl:non-matching-substring>                
        </xsl:analyze-string>                    
    </tr>
</xsl:template>

Upvotes: 1

Related Questions