You probably want to think about doing this in two stages; first, do a transform that breaks down these value attributes, then it's fairly trivial to count them.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@value">
<xsl:call-template name="breakdown">
<xsl:with-param name="itemlist" select="substring-before(substring-after(.,'['),']')" />
</xsl:call-template>
</xsl:template>
<xsl:template name="breakdown">
<xsl:param name="itemlist" />
<xsl:choose>
<xsl:when test="contains($itemlist,',')">
<xsl:element name="value">
<xsl:value-of select="normalize-space(substring-before($itemlist,','))" />
</xsl:element>
<xsl:call-template name="breakdown">
<xsl:with-param name="itemlist" select="substring-after($itemlist,',')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:element name="value">
<xsl:value-of select="normalize-space($itemlist)" />
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Aside from the 'catch all' template at the bottom, this picks up any value attributes in the format you gave, and breaks them down into separate elements (as sub-elements of the 'metadata_valuelist' element) like this:
...
<metadata_valuelist>
<value>SampleItem1</value>
<value>SampleItem2</value>
</metadata_valuelist>
...
The 'substring-before/substring-after select you see near the top strips off the '[' and ']' before passing it to the 'breakdown' template. This template will check if there's a comma in it's 'itemlist' parameter, and if there is it spits out the text before it as the content of a 'value' element, before recursively calling itself with the rest of the list. If there was no comma in the parameter, it just outputs the entire content of the parameter as a 'value' element.
Then just run this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:key name="itemvalue" match="value" use="text()" />
<xsl:template match="/">
<xsl:value-of select="count(//value[generate-id(.) = generate-id(key('itemvalue',.)[1])])" />
</xsl:template>
</xsl:stylesheet>
on the XML you get from the first transform, and it'll just spit out a single value as text output that tells you how many distinct values you have.
EDIT: I should probably point out, this solution makes a few assumptions about your input:
- There are no attributes named 'value' anywhere else in the document; if there are, you can modify the @value match to pick out these ones specifically.
- There are no elements named 'value' anywhere else in the document; as the first transform creates them, the second will not be able to distinguish between the two. If there are, you can replace the two
<xsl:element name="value">
lines with an element name that's not already used.
- The content of the @value attribute always begins with '[' and ends with ']', and there are no ']' characters within the list; if there are, the 'substring-before' function will drop everything after the first ']', rather than just the ']' at the end.
- There are no commas in the names of the items you want to count, e.g. [SampleItem1, "Sample2,3"]. If there are, '"Sample2' and '3"' would be treated as separate items.