rfossella
rfossella

Reputation: 127

XSL using matches and regular expressions

I have a simple for-each statement that matches nodes using a regular expression. I am looking inside nodes for any matches of 4 or more digits.

<xsl:for-each select="//methods/body[matches(., '= \d{4}')]">
    <p><xsl:value-of select="." /></p>
</xsl:for-each>

I am trying the get the VALUE of the matched value - i.e. if NodeA contains "xxxx yyyy 12345 zzzz" and NodeB contains "aaa bb 88555 cccc", I would like to print the values 12345 and 88555.

The code above will simply print the entire current NODE that matches.

Furthermore, I need to get distinct values. E.g. xxx 12345, yyy 56789, zzz 12345 I would need the result to be 12345 and 56789.

Is the matching pattern the best way to accomplish this? I got my initial (correct) set of nodes quickly, but stalled.

Upvotes: 2

Views: 3463

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52888

For the test, matches() works well. For actually pulling out the values, xsl:analyze-string is better.

Example...

XML Input

<doc>
    <x>xxxx yyyy 12345 zzzz</x>
    <x>aaa bb 88555 cccc</x>
    <x>xxxx yyyy 12345 zzzz aaa bb 88555 cccc</x>    
</doc>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/*">
        <xsl:variable name="values">
            <xsl:for-each select="x[matches(.,'\d{4}')]">
                <xsl:analyze-string select="." regex="\d{{4}}">
                    <xsl:matching-substring>
                        <xsl:sequence select="."/>
                    </xsl:matching-substring>
                </xsl:analyze-string>
            </xsl:for-each>
        </xsl:variable>
        <xsl:value-of select="distinct-values(tokenize($values,'\s'))" separator=", "/>
    </xsl:template>

</xsl:stylesheet>

Output

1234, 8855

Upvotes: 1

Related Questions