Re: [xsl] Grouping repeating elements within repeating elements

Subject: Re: [xsl] Grouping repeating elements within repeating elements
From: Cynthia.Arangua@xxxxxxxxxxxxxx
Date: Tue, 4 Dec 2007 12:03:42 -0600
This solution worked wonderfully but I have two more questions.  How would
you generate a unique id for each layer in the output?  I tried to do
generate-id(.) but in some cases, it generated the same id so I have tried
to add in documentum specific ids that it pulls from the database but not
sure I feel completely comfortable with that approach.  Also, how would we
produce the /category/content_category_faq if there we NO headings.  I am
trying to come up with a solution for that one right now as well.  Thanks!
-----"G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx> wrote: -----

To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: 11/26/2007 08:31PM
Subject: Re: [xsl] Grouping repeating elements within repeating elements

At 2007-11-26 13:08 -0700, Cynthia Arangua wrote:
>I have been doing XSLT for about four years now and this input XML
>has me a little stumped as to how to implement.  I believe I am
>using Xalan 2.6 (bundled as part of an EMC Documentum product called
>WebPublisher) and the only version it supports currently is XSLT 1.0.

This is a particularly difficult problem for XSLT 1.0 because of the
organization of the grouping.

>Here is the XML input:
>Basically, I need to group any category/content_category_faq under
>the appropriate heading designation so like the following:
>     Health
>         Medical Coverage
>               Medical Coverage-PPO
>               Medical Coverage-HMO
>         Dental
>      Financial
>           Flexible Spending
>Life Events
>      Getting Married
>      Adoption
>I am in the introductory stages on development on this so I don't
>have any existing XSL to demonstrate but I am hoping to make some
>headway today so I can repost but any initial help would be very
>cool.  I am working on some recurse logic as we speak.

I, too, had to use recursive logic to address this.

A complete solution is below.

As I've often posted, I'm using variables for grouping because of the
sub-document context (keys have document-wide context in XSLT 1.0 but
can be accessed in a limited fashion in XSLT 2.0).

What was interesting is the organization of your headers ... I made
the assumptions that the order is critically important:  it isn't
just that the headers are the same, but that the same headers are in
the same relative position to each other as children of FAQs.

I hope the code below helps ... the output matches your requirement.

. . . . . . . . . . Ken

T:\ftemp>type cindy.xml
<?xml version="1.0" encoding="UTF-8"?>
  <heading>Medical Coverage</heading>
     <content_category_faq>Medical Coverage - PPO</content_category_faq>
      <content_category_faq>Medical Coverage - HMO</content_category_faq>
    <content_category_faq>Flexible Spending</content_category_faq>
   <heading>Life Events</heading>
       <content_category_faq>Getting Married</content_category_faq>

T:\ftemp>type cindy.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="";

<xsl:output method="text"/>

<xsl:template match="/">
  <!--start everything off with the first heading using all FAQs
  <xsl:call-template name="next-heading">
    <xsl:with-param name="faqs" select="/content/faq_listing"/>

<!--process the next level of heading distinction-->
<xsl:template name="next-heading">
  <xsl:param name="index" select="1"/>
  <xsl:param name="indent" select="''"/>
  <xsl:param name="faqs" select="/.."/>
  <!--determine if there are any headings at this level-->
  <xsl:if test="$faqs[heading[$index]]">
    <!--then there are levels of heading still to separate-->
    <xsl:for-each select="$faqs">
      <xsl:if test="generate-id(.)=
        <!--this is a common heading, so display it-->
        <xsl:value-of select="concat($indent,heading[$index])"/><xsl:text>
        <!--determine if there is any information at the next level
of depth-->
        <xsl:call-template name="next-heading">
          <xsl:with-param name="index" select="$index + 1"/>
          <xsl:with-param name="indent" select="concat($indent,'     ')"/>
          <xsl:with-param name="faqs" select="$faqs[heading[$index]=

  <!--determine if there are any non-headings at this level-->
  <xsl:for-each select="$faqs[heading[$index - 1] and not( heading[$index]
    <!--and display them-->
    <xsl:value-of select="concat($indent,.)"/><xsl:text>

T:\ftemp>call xslt cindy.xml cindy.xsl cindy.txt

T:\ftemp>echo on

T:\ftemp>type cindy.txt
          Medical Coverage
               Medical Coverage - PPO
               Medical Coverage - HMO
          Flexible Spending
Life Events
     Getting Married

T:\ftemp>rem Done!

Comprehensive in-depth XSLT2/XSL-FO1.1 classes: Austin TX,Jan-2008
World-wide corporate, govt. & user group XML, XSL and UBL training
RSS feeds:     publicly-available developer resources and training
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Nov'07
Legal business disclaimers:

Current Thread