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
======================================================================
|
|