xsl-list
[Top] [All Lists]

Re: [xsl] Grouping repeating elements within repeating elements

2007-12-04 11:04:20

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(_at_)CraneSoftwrights(_dot_)com> wrote: -----


To: <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
From: "G. Ken Holman" <gkholman(_at_)CraneSoftwrights(_dot_)com>
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:

Benefits
    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"?>
<content>
<faq_listing>
  <heading>Benefits</heading>
  <heading>Health</heading>
  <heading>Medical Coverage</heading>
  <category>
     <content_category_faq>Medical Coverage - PPO</content_category_faq>
  </category>
  <category>
      <content_category_faq>Medical Coverage - HMO</content_category_faq>
  </category>
</faq_listing>
<faq_listing>
   <heading>Benefits</heading>
   <heading>Health</heading>
   <category>
      <content_category_faq>Dental</content_category_faq>
   </category>
</faq_listing>
<faq_listing>
<heading>Benefits</heading>
<heading>Financial</heading>
  <category>
    <content_category_faq>Flexible Spending</content_category_faq>
  </category>
</faq_listing>
<faq_listing>
   <heading>Life Events</heading>
   <category>
       <content_category_faq>Getting Married</content_category_faq>
   </category>
   <category>
     <content_category_faq>Adoption</content_category_faq>
   </category>
</faq_listing>
</content>

T:\ftemp>type cindy.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output method="text"/>

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

<!--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(.)=
                    generate-id($faqs[heading[$index]=
                                      current()/heading[$index]])">
        <!--this is a common heading, so display it-->
        <xsl:value-of select="concat($indent,heading[$index])"/><xsl:text>
</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]=
                                                  current()/heading[$index]]"/>

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

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

T:\ftemp>echo on

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

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(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>