Can someone explain this snippet? Muenchian sorting.

Can someone explain this snippet? Muenchian sorting.

Post by Jim Bancrof » Sat, 05 Jul 2003 00:34:23



I've been reading up on the "Muenchian" sorting method on
www.jenitennison.com, and saw this use of the count() function:

<xsl:for-each select="contact[count(. | key('contacts-by-surname',
surname)[1]) = 1]">

    What's happening is the code is trying to select the first node in a
set, given a particular key.  At least that's what I think.

    Anyway, the "count(. | key('contacts-by-surname', surname)[1]) = 1" bit
is throwing me for a loop, I can't figure out what's going on there.  Are
you trying to OR the current context node with the first value of the node
set returned from the key() function?  What happens when you do that?

    Another way of doing the same thing seems to be as follows, (and thanks
to Marrow for helping me with a similar problem yesterday):

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

    I understand this a little more, it looks like you want the node whose
id (conveniently created via "generate-id()") matches the first one returned
by the key.  Please correct me if I misunderstood that or any other portion
of the code I posted.  Thanks!

-Jim

 
 
 

Can someone explain this snippet? Muenchian sorting.

Post by Colin Mackenzi » Sat, 05 Jul 2003 00:45:11


see below


Quote:> I've been reading up on the "Muenchian" sorting method on
> www.jenitennison.com, and saw this use of the count() function:

> <xsl:for-each select="contact[count(. | key('contacts-by-surname',
> surname)[1]) = 1]">

>     What's happening is the code is trying to select the first node in a
> set, given a particular key.  At least that's what I think.

>     Anyway, the "count(. | key('contacts-by-surname', surname)[1]) = 1"
bit
> is throwing me for a loop, I can't figure out what's going on there.  Are
> you trying to OR the current context node with the first value of the node
> set returned from the key() function?  What happens when you do that?

the current context node . is being OR'd (a "set" operation) with the first
node returned from the key (as you say) to contain a node set with a
combination of both nodes
IF the current node IS the same node as that returned from the key then the
combined node set will only contain ONE node, therfore count(the combined
nodeset) would = 1
Therefore the count = 1 is True for that node, the [] predicate is true and
the node is processed by the logic within for-each (and so you get the first
name in the set presumably)

Quote:>     Another way of doing the same thing seems to be as follows, (and
thanks
> to Marrow for helping me with a similar problem yesterday):

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

>     I understand this a little more, it looks like you want the node whose
> id (conveniently created via "generate-id()") matches the first one
returned
> by the key.  Please correct me if I misunderstood that or any other
portion
> of the code I posted.  Thanks!

yes you are correct, but remeber the predicate [] portion is resolving to
true or false and can return true for multiple nodes (the first occurence of
a surname in a list)
Quote:

> -Jim


 
 
 

Can someone explain this snippet? Muenchian sorting.

Post by Marro » Sat, 05 Jul 2003 16:01:17


Hi Jim,

Quote:>     Anyway, the "count(. | key('contacts-by-surname', surname)[1]) = 1"
bit
> is throwing me for a loop, I can't figure out what's going on there.  Are
> you trying to OR the current context node with the first value of the node
> set returned from the key() function?  What happens when you do that?

It is usually best to keep in mind that the | operator is union (rather than
OR).

When, in XPath, you do a union of two node-sets the resulting node-set will
only ever contain each individual node once (i.e. a node-set can never
contain a particular node twice or more).

There are some common patterns of XPath/XSLT that you get used to seeing -
two in particular are...
  count(. | something[1]) = 1
and...
  generate-id(.) = generate-id(something[1])
Both of these are saying...
  is the current context node (.) the same actual node as the something[1]
node

Quote:> <xsl:for-each select="contact[count(. | key('contacts-by-surname',
> surname)[1]) = 1]">

For every <contact> node check if this <contact> is the same as the first
<contact> node returned by the key 'contacts-by-surname' for this value of
the <contact>'s child <surname> element.

See also: http://www.veryComputer.com/

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

Is doing much the same - but comparing the two generated ids to see if this
<contact> is the first one with this value of <surname>.

A couple of tips:-
1) the generate-id() variation of the Muenchian Technique is usually
(always?) faster;
2) when using the generate-id() variation the index predicate (i.e. the
'[1]' part) is completely superfluous because generate-id() only ever
returns the generated id of the first node in the passed node-set.  In most
transformation engines adding the '[1]' index predicate will have a slight
(but cumulative) performance impact - because you are doing something that
the generate-id() function will do anyway.

Cheers
Marrow
http://www.veryComputer.com/ - home of Xselerator (XSLT IDE and de*)
http://www.veryComputer.com/


Quote:> I've been reading up on the "Muenchian" sorting method on
> www.jenitennison.com, and saw this use of the count() function:

> <xsl:for-each select="contact[count(. | key('contacts-by-surname',
> surname)[1]) = 1]">

>     What's happening is the code is trying to select the first node in a
> set, given a particular key.  At least that's what I think.

>     Anyway, the "count(. | key('contacts-by-surname', surname)[1]) = 1"
bit
> is throwing me for a loop, I can't figure out what's going on there.  Are
> you trying to OR the current context node with the first value of the node
> set returned from the key() function?  What happens when you do that?

>     Another way of doing the same thing seems to be as follows, (and
thanks
> to Marrow for helping me with a similar problem yesterday):

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

>     I understand this a little more, it looks like you want the node whose
> id (conveniently created via "generate-id()") matches the first one
returned
> by the key.  Please correct me if I misunderstood that or any other
portion
> of the code I posted.  Thanks!

> -Jim

 
 
 

Can someone explain this snippet? Muenchian sorting.

Post by Jim Bancrof » Wed, 09 Jul 2003 00:51:16


Thanks again for the explanation, Marrow.

I hate to ask for another favor, you've been really helpful, but could I ask
you a question about this?  It's from a post you showed me on July 2nd:

<!---------------------------------------------------------------->
<xsl:key name="kDistinctPartName" match="part" use="name"/>
<!--more stuff goes here, snip-->

<!-- copy only the highest version of this distinct part name -->


<!------------------------------------------------------------------>



attribute is *not* less than the one returned by the key.  My question is:
are you only comparing the first element of the key, or does the &lt;

Sorry for the trouble!

-Jim

 
 
 

Can someone explain this snippet? Muenchian sorting.

Post by Marro » Wed, 09 Jul 2003 02:06:32


Hi Jim,

Quote:> Sorry for the trouble!

No trouble at all. :)


little

> attribute is *not* less than the one returned by the key.  My question is:
> are you only comparing the first element of the key, or does the &lt;



Remember that the key() function just returns a node-set... so it is the
usual process of comparing node-sets.

Cheers
Marrow


> Thanks again for the explanation, Marrow.

> I hate to ask for another favor, you've been really helpful, but could I
ask
> you a question about this?  It's from a post you showed me on July 2nd:

> <!---------------------------------------------------------------->
> <xsl:key name="kDistinctPartName" match="part" use="name"/>
> <!--more stuff goes here, snip-->

> <!-- copy only the highest version of this distinct part name -->


> <!------------------------------------------------------------------>


little

> attribute is *not* less than the one returned by the key.  My question is:
> are you only comparing the first element of the key, or does the &lt;

> Sorry for the trouble!

> -Jim

 
 
 

1. Can someone explain what I should expect in this sample?

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q271239

I put all their files sample.xml, template.htm and test.htm in my server.
Changed myserver and built the dll.  When I fire up test.htm I see a
wonderful empty page.  And I get a ActiveX warning.  That's it.

--
George Hester
__________________________________

2. HELP. SCO named problem

3. Can someone please explain?

4. intranet e mail

5. Can someone explain <!DOCTYPE>?

6. Oracle Jobs Eastern U.S. $$$

7. Can someone explain <!NOTATION in dtd?

8. Could Someone Explain Please

9. XSL and XSLT, can someone explain

10. Help with a beginners code snippet

11. XERCES: Whats the simplest code snippet to import an XML file?

12. how specify dtd for this xml snippet?