This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

New approach to grouping problem that doesn't use keys or axes


At 01/10/16 16:40 -0400, Langdon, Jeffrey wrote:
>I have an XML file that includes
>a list of employees and their respective departments.  I need to loop
>through the xml and sort the employees by department alphabetically.

You don't mention if you are using a processor that does or does not 
support the key() function, so I thought I would share something I figured 
out last month when I was in a position of being obliged to use a processor 
that does not.

An alternative available in some situations to using the full Muenchian 
method is a hybrid method using variables.  This turned out to be *very* 
handy when grouping within subtrees, as using the Muenchian method for 
subtrees involves an elaborate key building approach as documented in:

   http://www.biglist.com/lists/xsl-list/archives/200011/msg00757.html

One property variables share with key tables is that their members are in 
document order, thus at any time during the process (not just at the very 
start when building key tables), one can create a locally-scoped variable 
with only those nodes that need to be grouped.  Then, as we learned from 
the Muenchian method, the use of the generated identifier for a node can 
determine the first node in document order for a given value.

Your problem is solved below using a locally-scoped variable to illustrate 
how this grouping can be done easily when in a subtree of a much larger 
source node tree.

>I am not sure how to make the (Name) TreeNode element a child element of
>the (Department) TreeNode element and then populate all the employees
>within that department.
>...
>Here is the XML file -
>
><NewDataSet>
>...
>                         <cn>Belki Hercules</cn>
>                         <Department>ITl</Department>
>                         <Name>Belki Hercules</Name>

I'm assuming from the result that the above Department has a typo and 
should be "IT" not "IT1".

Please find below the hybrid grouping approach using variables that 
successfully runs with the XT processor that does not support the xsl:key 
instruction or key() function.  I've successfully used this locally-scoped 
grouping approach a few times since then, and I've updated the upcoming 
10th edition of my "Practical Transformation Using XSLT and XPath" book 
with this algorithm.  I hope the 10th edition will be out soon, and it will 
of course be free to all customers who have purchased any earlier edition.

When I taught this last week in instructor-led training as one step 
*before* teaching the Muenchian method, the class seemed to catch on to the 
full Muenchian method much more quickly.  Note that my approach does not 
deliver a node set the way the Muenchian method does, but not every 
grouping solution needs an intermediate node set.  But for those that do, I 
still teach the Muenchian method as the next step in sophistication after 
teaching this local-variable approach.

And, when I was obliged to use XT, this approach solved my grouping problem 
much faster than using the source node tree axes.  Oh, and in that case I 
ended up using a global variable instead of a local variable because my 
groups were scoped across the entire document, but that doesn't change the 
algorithm at all, just where the variable is declared.

I hope you find this useful.

......................... Ken

T:\jeff>type jeff.xml
<NewDataSet>
             <Table>
                         <cn>Acevedo, Antonia</cn>
                         <Department>Dispatch-Freight</Department>
                         <Name>Acevedo, Antonia</Name>
             </Table>
             <Table>
                         <cn>Aimone, Charlie</cn>
                         <Department>IT</Department>
                         <Name>Aimone, Charlie</Name>
             </Table>
             <Table>
                         <cn>Arenas, Lizalyn</cn>
                         <Department>Dispatch-Freight</Department>
                         <Name>Arenas, Lizalyn</Name>
             </Table>
             <Table>
                         <cn>Arrendell, Miguel</cn>
                         <Department>Warehouse</Department>
                         <Name>Arrendell, Miguel</Name>
             </Table>
             <Table>
                         <cn>Bayron, Jun</cn>
                         <Department>Warehouse</Department>
                         <Name>Bayron, Jun</Name>
             </Table>
             <Table>
                         <cn>Belki Hercules</cn>
                         <Department>IT</Department>
                         <Name>Belki Hercules</Name>
             </Table>
</NewDataSet>

T:\jeff>type jeff.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
   <TREENODE>
     <xsl:apply-templates/>
   </TREENODE>
</xsl:template>

<xsl:template match="NewDataSet">
   <xsl:variable name="tables" select="Table"/>
   <xsl:for-each select="$tables">
     <xsl:sort select="Department"/>
     <xsl:variable name="dept" select="Department"/>
     <xsl:if test="generate-id(.)=
                   generate-id($tables[Department=$dept])">
       <!--found first of each department in document order-->
       <TreeNode Text="{$dept}">
         <xsl:for-each select="$tables[Department=$dept]">
           <TreeNode Text="{Name}"/>
         </xsl:for-each>
       </TreeNode>
     </xsl:if>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

T:\jeff>xt jeff.xml jeff.xsl
<?xml version="1.0" encoding="utf-8"?>
<TREENODE>
<TreeNode Text="Dispatch-Freight">
<TreeNode Text="Acevedo, Antonia"/>
<TreeNode Text="Arenas, Lizalyn"/>
</TreeNode>
<TreeNode Text="IT">
<TreeNode Text="Aimone, Charlie"/>
<TreeNode Text="Belki Hercules"/>
</TreeNode>
<TreeNode Text="Warehouse">
<TreeNode Text="Arrendell, Miguel"/>
<TreeNode Text="Bayron, Jun"/>
</TreeNode>
</TREENODE>



--
G. Ken Holman                      mailto:gkholman@CraneSoftwrights.com
Crane Softwrights Ltd.               http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0     +1(613)489-0999   (Fax:-0995)
Web site:     XSL/XML/DSSSL/SGML/OmniMark services, training, products.
Book:  Practical Transformation Using XSLT and XPath ISBN 1-894049-06-3
Article: What is XSLT? http://www.xml.com/pub/2000/08/holman/index.html
Next public training (instructor-live, Internet-live, and web-based):
-2001-10-22,11-01,11-02,11-05,11-19,11-21,12-03,12-05,12-09,12-10,12-19


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]