xsl-list
[Top] [All Lists]

Re: Identity Transform Grouping Question

2004-10-14 14:54:02
Ethan,

You've found that preceding::, or any axis, refers to nodes' placement in the original hierarchy, and not to a sorted order.

When we absolutely have to do this, we do it in two passes: first sort, then transform our results, where the sorted order is now the "original" order of the input.

Such kinds of processing-the-results can actually be achieved in a single run of a stylesheet if a node-set() extension is used -- which is one reason why this is a confusing issue. Being able to turn a result tree into a node set for further processing is both really powerful, and liable to make people's brains spin off their bearings. Caution is warranted.

Because this is so inconvenient, however, we also often use various tricks and methods to avoid having to do it. In your case, this might be achieved by doing the grouping *before* you do the sorting (though I haven't worked it out well enough to be certain of this). Select a representative node from each set you want to group (this is the essence of the Muenchian method); for each one, create a wrapper and inside it, pull the entire group -- only sorting at that point. This approach is more XSLT-friendly than processing them sorted and then trying to group them as you go by checking the preceding:: axis (which won't see which nodes have "already been hit").

This stuff is hard in XSLT 1.0 because it goes beyond the bounds of what the language was originally designed for, though not beyond what it is commonly used for.

Cheers,
Wendell

At 12:08 PM 10/14/2004, you wrote:
<<Node trees don't contain markup, so don't have tags, and you can't have half a node, so you can never insert a closing tag anywhere, in particular you can't insert one at the location of this comment. The way to put a group of nodes as child elements of another node is to first create the wrapper node <foo> then inside that select all the elements that should go in the group </foo>
>>
Perhaps my comments are misleading. My intent _is_ to explicitly wrap each unique group of <location> nodes -- that is, <location> nodes belonging to a unique <office> node -- with a surrounding <office></office> node (I said "tags" because my result tree is saved as an new xml file as input to another process -- so I am conceptualizing what that resulting xml file will look like, markup and all). My comments include complete markup (opening and closing tags) for this wrapper node; it is commented out because I could not successfully generate the wrapper node for each unique group, but wanted to show where the wrapper node should exist within the result tree.
<<actually I'm not sure _why_ you are using msxsl:node-set() >>
Some of the XSLT, including this technique, was provided to me by another person on another site in order to assist me with using the Muenchian method for grouping <office> nodes within unique <city> nodes. A somewhat general explanation of my goal is that I want to sort the source tree according to several sort levels, then perform an identity transform that would reverse the parent-child relationship between the <city> and <office> nodes, and, finally, group <office> nodes according to their English name (office/names/name[(_at_)lang='en']), with each <office> node having one or more new <location> nodes to wrap the location-specific information, thus eliminating duplicate office/names nodes with the same name child. (I hope this is somewhat helpful!) As I said, the current XSLT works wonderfully (transforming a 3MB file in 2 seconds) until the point of detail where I need to eliminate the duplicate office/names nodes. My XSLT seems to fail based on the mistaken idea that the use of preceding-sibling works with sorted nodes, which I now know it does not. So, the question is...once I have a sorted node set, what technique can I use to group those nodes according to a specific node value? Specifically, how do I ensure that the result tree contains office/names nodes with a unique name child (determined by the 'lang' attribute value = 'en')?


======================================================================
Wendell Piez                            
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================