If you're trying to do this in XSLT 1.0, You should be able to do something like this xsl: how to split strings?, and maybe using a document()
function if it's supported by your processor to load the results of that into a document and then maybe use an xsl:key
to get the distinct results. It's pretty convoluted though. Here is another method that avoids some of that convolution using pure XSLT 1.0: https://stackoverflow.com/a/34944992/3016153.
My preference would still be for some kind of extension for this; if you're doing this using MSXML, you could do something like the following (I'd probably prefer C# here, but JavaScript is probably more portable if you're not using MSXML):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="http://mycompany.com/mynamespace">
<xsl:template match="/base/string">
<xsl:value-of select="user:distinctSplit(string(.))" />
</xsl:template>
<msxsl:script language="JScript" implements-prefix="user">
function distinctSplit(str) {
var u = {}, a = [];
var splt = str.split(',');
for(var i = 0;i < splt.length;i++) {
if (u.hasOwnProperty(splt[i])) {
continue;
}
a.push(splt[i]);
u[splt[i]] = 1;
}
return a.join(',');
}
</msxsl:script>
</xsl:stylesheet>
If you're not using MSXML, you might be able to get a tokenize extension or use your processor's method of embedding JavaScript (and your processor might even support the .filter()
function for arrays, which could make this code simpler - testing locally with MSXML didn't support filter()
for me).
If you're using XSLT 2.0, you could use tokenize
and distinct-values
, something like this should work:
<xsl:for-each select="distinct-values(tokenize(/base/string, ','))" separator=",">
<xsl:value-of select="concat(., ',')" />
</xsl:for-each>
but you might have to play with it a little as it may add extra ,
literals that you don't want at the end.