I saw this line of code in an implementation of the Muenchian method:
<xsl:for-each
select="//product[count(. | key('products-by-category', @category)[1]) = 1]">
I don't get what is happening with count()
. I think that count(.)
means count(self::product)
, which is always 1, and the pipe operator (|) adds the first node that matches the key, but shouldn't the key 'products-by-category' always return a node-set, given that product has the 'category' attribute and therefore match itself?
In which elements this for-each loop iterates? Can you provide a natural language translation for this expression? Thanks.
In XPath 1.0, the expression count($x|$y)=1
is used to test whether $x and $y are the same node. In 2.0, you can use the more intuitive expression $x is $y
. It works because if both $x and $y are singleton sets, then the union of the two sets will contain two nodes if they are different, but only one if they are the same.
In this example, the expression is being used to ask "is the current node the first one with its particular key value", which is the critical test used in Muenchian grouping.
Another way of doing the same test in XPath 1.0 is the expression generate-id($x) = generate-id($y)
. You will see both forms used.
Can you provide a natural language translation for this expression?
Shortly, it means "for each product that is first in its category".
How so? It takes all product elements, anywhere in your document:
<xsl:for-each select="//product">
and filters them by the expression:
[count(. | key('products-by-category', @category)[1]) = 1]
in this expression, this part:
key('products-by-category', @category)[1])
refers to the first product node in the same category as the one of the currently evaluated product.
Now, if the currently evaluated product is also the first product in its category, then counting the two together will return 1. Otherwise, there would be two distinct nodes to count, and the result would be 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With