1

I am trying to understand the meaning of MUENCHIAN METHOD used in XSLT to group nodes.

But I am not able to understand the significance of some of the statements which are used.

I referred link here which tries to explain the same.

There is this statement:

contact[generate-id() = generate-id(key('contacts-by-surname', surname)[1])]

In this I could understand that generate-id() gives a unique id assigned to the current node which is being traversed. But not able to understand the reason behind accessing the the first element i.e. 1.

Why only first? I do know that key function does create an associative array kind of representation.

Can someone guide me on this?

Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
Sam
  • 2,352
  • 4
  • 32
  • 45
  • 2
    Maybe my explanation of `` in [this answer](http://stackoverflow.com/a/955527/18771) helps you (read the lower part, where I go into detail about it). – Tomalak Mar 12 '14 at 10:03
  • 2
    The link you've already referred to is the canonical explanation of Muenchian grouping, and is one of the clearest descriptions I've seen anywhere. The point is that you need to process just one node with each key value, and the one that comes first in document order is as good as any. You could equally use `[last()]` instead of `[1]` to extract the last one instead of the first, that would give you the same groups but not necessarily in the same order. – Ian Roberts Mar 12 '14 at 10:23

2 Answers2

4

Many XPath functions take the current node as input if you don't give any input yourself. string() or number() or generate-id() do that, for example.

Therefore generate-id() is eqivalent to generate-id(.).


If you pass in an entire set of nodes as the argument, they work on the first node only.

string(//foo) will return the string representation of the first <foo> in the document, no matter how many others there are.

The same is true for generate-id(). generate-id(//foo) will return the unique ID of the first <foo> in the document.

Therefore, generate-id(key('keyname', 'keyvalue')) gives the unique ID of the first node of whatever key() returns.

Using [1], as in generate-id(key('keyname', 'keyvalue')[1]) is not strictly necessary, it's just more explicit.


So the expression

contact[generate-id() = generate-id(key('contacts-by-surname', surname)[1])]

can be read as

Any <contact> where its ID is equal to the ID of the first (<contact> with the same <surname>).

Here the "(contact with a given surname)" part is what's handled by key().

or, more abstractly

Any <contact> that is the first in its <surname> group.

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • +1 , And of course the point of generating the ID of the first node returned by the key invocation is to have a means of identifying the different groups, that is, to determine what an `xsl:for-each` should iterate over to mimic XSLT 2.0's `xsl:for-each-group`. – Mathias Müller Mar 12 '14 at 10:22
  • Exactly, that's the implication. (In fact that is one of the few occations where I prefer `` over ``.) – Tomalak Mar 12 '14 at 10:30
  • @Tomalak So when we do [1] or not do it at all how can we sure that the last returned node is not the one which is currently returned again by key() function? I mean if "1:83" points to array of all nodes with @AreaID="1" and @UnitID="83" then how can I be sure that the last accessed is not the one which is being accessed now? Also what does contact[] gets in contact[count(. | key('contacts-by-surname', surname)[1]) = 1]? When I debugged it says contact[true / false]. – Sam Mar 13 '14 at 14:41
  • I'm afraid I don't understand that question. Also you seem to refer to my answer in the *other* thread. (But please don't start a discussion there, having too many comments under an answer is not very helpful.) I guess you will have to read different explanations of XSL keys again and again and again until it sinks in. – Tomalak Mar 13 '14 at 18:18
-1

Go through http://www.learn-xslt-tutorial.com/Working-with-Keys.cfm

This will explain to the bits.

Brij
  • 11,731
  • 22
  • 78
  • 116