xsl-list
[Top] [All Lists]

Re: recursive sub-grouping

2004-08-23 12:07:53
Mukal,

That works perfectly, you're a star, thanks!

Robin

On 23 Aug 2004, at 16:10, Mukul Gandhi wrote:

Hi Robin,
  Please try this XSL. The XSL uses nodeset extension
function..

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xalan="http://xml.apache.org/xalan";>
<xsl:output method="xml" indent="yes"/>
        
<xsl:key name="by-language" match="video-file"
use="language"/>
<xsl:key name="by-format" match="temp1/video-file"
use="format"/>
<xsl:key name="by-bandwidth" match="temp2/video-file"
use="bandwidth"/>
        
<xsl:template match="/video-files">
  <languages>
    <xsl:for-each select="video-file">
      <xsl:if test="generate-id(.) =
generate-id(key('by-language', language)[1])">
        <language>
          <name>
            <xsl:value-of select="language"/>
          </name>
          <xsl:variable name="rtf1">
            <temp1>
              <xsl:copy-of select="key('by-language',
language)"/>
            </temp1>
          </xsl:variable>
          <formats>
            <xsl:for-each
select="xalan:nodeset($rtf1)/temp1/video-file">
              <xsl:if test="generate-id(.) =
generate-id(key('by-format', format)[1])">
                 <format>
                   <name>
                     <xsl:value-of select="format"/>
                   </name>
                   <xsl:variable name="rtf2">
                     <temp2>
                       <xsl:copy-of select="key('by-format',
format)"/>
                     </temp2>
                   </xsl:variable>
                   <bandwidths>
                     <xsl:for-each
select="xalan:nodeset($rtf2)/temp2/video-file">
                        <xsl:if test="generate-id(.) =
generate-id(key('by-bandwidth', bandwidth)[1])">
                          <badwidth>
                            <name>
                              <xsl:value-of select="bandwidth"/>
                            </name>
                          </badwidth>
                        </xsl:if>
                     </xsl:for-each>
                   </bandwidths>
                 </format>
               </xsl:if>
             </xsl:for-each>
           </formats>
         </language>
       </xsl:if>
     </xsl:for-each>
   </languages>
 </xsl:template>
</xsl:stylesheet>

Regards,
Mukul

--- Robin Wyles <rob(_at_)robinwyles(_dot_)com> wrote:

Hi,

I am stuck on a transformation that requires me to
group and sub-group
a set of nodes based on their child nodes. My
starting XML is as
follows:

-------------- SOURCE ---------------
<?xml version="1.0"?>
<video-files>
        <video-file>
                <language>English</language>
                <format>Real</format>
                <bandwidth>Low</bandwidth>
        </video-file>
        <video-file>
                <language>English</language>
                <format>Real</format>
                <bandwidth>High</bandwidth>
        </video-file>
        <video-file>
                <language>English</language>
                <format>QuickTime</format>
                <bandwidth>Low</bandwidth>
        </video-file>
        <video-file>
                <language>English</language>
                <format>QuickTime</format>
                <bandwidth>High</bandwidth>
        </video-file>
        <video-file>
                <language>French</language>
                <format>Real</format>
                <bandwidth>Low</bandwidth>
        </video-file>
        <video-file>
                <language>French</language>
                <format>Real</format>
                <bandwidth>High</bandwidth>
        </video-file>
        <video-file>
                <language>French</language>
                <format>QuickTime</format>
                <bandwidth>Low</bandwidth>
        </video-file>
        <video-file>
                <language>French</language>
                <format>QuickTime</format>
                <bandwidth>High</bandwidth>
        </video-file>
</video-files>
-------------------------

And the final XML is to be as follows:

---------- FINAL ---------
<?xml version="1.0"?>
<languages>
        <language>
                <name>English</name>
                <formats>
                        <format>
                                <name>Real</name>
                                <bandwidths>
                                        <bandwidth>
                                                <name>High</name>
                                        </bandwidth>
                                        [...]
                                </bandwidths>                             
                        </format>
                        [...]
                </formats>
        <language>
        [...]
</languages>
-----------------------------

I have searched the list for some pointers to a
solution for this
problem and I have found plenty on grouping and
sub-grouping but I have
had limited success in applying the techniques to my
situation. The
initial grouping of the languages is no problem, but
I am not sure how
to approach the sub-grouping on the current language
group into format
groups, and then sub-group each of these into the
bandwidth groups. I
have a feeling that I need to generate keys for the
different
language/format/bandwidth combinations, but I am not
sure how to
implement this. For what it's worth my current XSLT
is as follows:

------------ XSLT -------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

        <xsl:key name="languages" match="video-file"
use="language"/>
        <xsl:key name="formats" match="video-file"
use="concat(language, '+',
format)"/>
        <xsl:key name="bandwidths" match="video-file"
use="concat(language,
'+', format, '+', bandwidth)"/>

        <xsl:template match="video-files">
                <languages>
                        <xsl:for-each

select="video-file[generate-id(.)=generate-id(key('languages',

language)[1])]">
                                <xsl:for-each select="key('languages',
language)">
                                        <xsl:sort select="format"/>
                                        <language>
                                                <xsl:if test="position() = 1">
                                                        <name><xsl:value-of
select="language"/></name>
                                                </xsl:if>
                                                <formats>
                                                        <!--- Need to do sub 
grouping here -->
                                                </formats>
                                        </language>
                                </xsl:for-each>
                        </xsl:for-each>
                </languages >
        </xsl:template>
</xsl:stylesheet>
--------------------------------

If anyone has any advice on the best way to approach
this problem (XSLT
1.0 only if possible), I would appreciate it.

Thanks,

Robin



                
_______________________________
Do you Yahoo!?
Win 1 of 4,000 free domain names from Yahoo! Enter now.
http://promotions.yahoo.com/goldrush

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