This may also be possible using [not(.=following::ATTRIBUTE)]
Here's a sample of something done in the past to ensure a unique list from node values (in this case, a list of area names, to form a dropdown with unique values). The syntax is a bit lighter but might not work in all circumstances. This might also help -> http://stackoverflow.com/questions/153156/xslt-how-to-count-distinct-values-in-a-node
Hmm. The syntax will change when using attribute and note nodes. I've just quickly tested the following code on a site I'm working on (searching for unique page headers), so give it a shot and let me know how you get on.
This is what seemed to work for me.
<xsl:variable name="unique-list" select="$currentPage//node/data[@alias='pageHeading' and not(.=following::node/data[@alias='pageHeading'])]" />
So this may work for you
<xsl:variable name="unique-list" select="$product//node/data[@alias='productCover' and not(.=following::node/data[@alias='productCover'])]" />
Worth a shot!
I do with xslt2 was in umbraco,it would be as easy as
@Dan... you're right, XSLT 2.0 would be nice. But until then, don't forget the umbraco library and the EXSLT extensions built-in to umbraco. You can get distinct results with:
This will return a node-set fragment so depending on how you want to use the result you may need to use the msxsl:node-set() function to convert the output back to a full node-set.
Without getting into the keys thing (which I should read up on at some stage)
2. You'll need to add the relevant headers to the xslt file to use exslt. Here's the head of a file with all (i think) of the available headers, then just use it like in dougs suggestion
Anthony, to be honest never got it to work either unless I was working with a key of integer type, which is just not what I wanted. I ended up writing a user control and use c# to do the grouping and sorting.
Doug's suggestion seems fine, altho not sure about the Exslt.ExsltSets:distinct($nodeset). Do you need the first 'Exslt'?
Value cannot be null. Parameter name: type Value cannot be null. Parameter name: type at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) at umbraco.presentation.xslt.Exslt.ExsltCommon.ExsltNodeListToXPathNodeIterator(ExsltNodeList list) at umbraco.presentation.xslt.Exslt.ExsltSets.distinct(XPathNodeIterator nodeset)
xslt distinct
if it possible to return distinct results.
ie
<xsl:for-each select="$productCover/descendant::node [@nodeTypeAlias = 'productFabric']">
if my @nodeName = "Linen" only show once
Hi Anthony, that is possible, let me find that example...
Here we go: http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx
Cheers,
/Dirk
bookmarked that link, cheers Dirk!
This may also be possible using [not(.=following::ATTRIBUTE)]
Here's a sample of something done in the past to ensure a unique list from node values (in this case, a list of area names, to form a dropdown with unique values). The syntax is a bit lighter but might not work in all circumstances. This might also help -> http://stackoverflow.com/questions/153156/xslt-how-to-count-distinct-values-in-a-node
thanks, really interesting replies.
i'm trying out Dan's example. I have something like this. I want to match by @nodeName.
As you see "count($unique-list)" // returns 28
But for some reason i can't foreach or get @nodeName from it.
<xsl:variable name="productCover" select="$product/descendant::node [@nodeTypeAlias = 'productCover']"/> <xsl:variable name="unique-list" select="$productCover//nodeName[not(.=following::nodeName)]" />
<xsl:value-of select="count($unique-list)"/> // returns 28 <xsl:for-each select="$unique-list/descendant::node [@nodeTypeAlias = 'productFabric']">
Here is the xslt that show all results without "not"
<xsl:variable name="productCover" select="$product/descendant::node [@nodeTypeAlias = 'productCover']"/> <xsl:for-each select="$productCover/descendant::node [@nodeTypeAlias = 'productFabric']">
sorry. i mean @nodeName
<xsl:variable name="unique-list" select="$productCover//@nodeName[not(.=following::nodeName)]" />
Hmm. The syntax will change when using attribute and note nodes. I've just quickly tested the following code on a site I'm working on (searching for unique page headers), so give it a shot and let me know how you get on.
This is what seemed to work for me.
So this may work for you
Worth a shot!
I do with xslt2 was in umbraco,it would be as easy as
Good luck,
Dan
* "note nodes" = "not nodes"
@Dan... you're right, XSLT 2.0 would be nice. But until then, don't forget the umbraco library and the EXSLT extensions built-in to umbraco. You can get distinct results with:
This will return a node-set fragment so depending on how you want to use the result you may need to use the msxsl:node-set() function to convert the output back to a full node-set.
cheers,
doug.
Sweet! I always overlook exslt. sets:distinct seems to do the trick exactly. Bookmarked http://exslt.org/set/functions/distinct/index.html
Cheers Doug
lots of options here. I've tried them all. Still no luck.
1) I tried dirk's http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">suggestion
here's where i got. No results.
<xsl:key name="nodeMatch" match="node" use="@alias='selectFabric'"/> <xsl:template match="/"> <xsl:variable name="nodeset" select="$productCover/descendant::node [@nodeTypeAlias = 'productFabric'] "/>
<xsl:for-each select="$nodeset/node[generate-id() = generate-id(key('nodeMatch', data[@alias='selectFabric'])[1])]"> <xsl:value-of select="data [@nodeName]"/> </xsl:for-each>
2) Doug's Exslt.ExsltSets:distinct($nodeset)
This gave me a parsing error. Is this really in use. It's not a very noisey keyword in the forums.
3) Dan's not statement. I'm getting no results.
<xsl:variable name="nodeset" select="$productCover/descendant::node [@nodeTypeAlias = 'productFabric'] "/> <xsl:variable name="uniquelist" select="$nodeset/data[@alias='selectFabric' and not(.=following::node/data[@alias='selectFabric'])]" /> <xsl:for-each select="$uniquelist"> <xsl:value-of select="@nodeName"/> </xsl:for-each>
anyway, really appreciate all the tips.
Anthony
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx">
Without getting into the keys thing (which I should read up on at some stage)
2. You'll need to add the relevant headers to the xslt file to use exslt. Here's the head of a file with all (i think) of the available headers, then just use it like in dougs suggestion
3. Your syntax looks ok in the select statements, so I'd print out uniquelist before going through it. At the very least, it would be
but I'd copy it to the screen to see what it's made up of.
Good luck!
Dan
Anthony, to be honest never got it to work either unless I was working with a key of integer type, which is just not what I wanted. I ended up writing a user control and use c# to do the grouping and sorting.
Doug's suggestion seems fine, altho not sure about the Exslt.ExsltSets:distinct($nodeset). Do you need the first 'Exslt'?
Cheers;
/Dirk
@dirk - I think so - to do a calendar recently (possibly part of a future project) I found that
Is what is needed to get it working.
@dirk ah ok. Yeah might just have to c# it.
@dan, really appreciate your help. I think it i was just dealing with $currentPage it might be easier to use your method.
For interest, here is the stack trace for Exslt.ExsltSets:distinct($nodeset). I added the correct xslt namespaces as suggested by dan.
<xsl:if test="$nodeset!= ''">
<xsl:value-of select="Exslt.ExsltSets:distinct($nodeset)" /> </xsl:if>
Parameter name: type
Value cannot be null.
Parameter name: type
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at umbraco.presentation.xslt.Exslt.ExsltCommon.ExsltNodeListToXPathNodeIterator(ExsltNodeList list)
at umbraco.presentation.xslt.Exslt.ExsltSets.distinct(XPathNodeIterator nodeset)
Hi
I'm getting the same problem, anyone solved the riddle yet?
-Kim
is working on a reply...