Re: Flat puzzle. (Re: <xsl:stylesheet xmlns...)

Subject: Re: Flat puzzle. (Re: <xsl:stylesheet xmlns...)
From: "Steve Muench" <smuench@xxxxxxxxxxxxx>
Date: Mon, 7 Aug 2000 00:23:14 -0700
Paul,

| This is very  good. I wish you already got something  like 
| 'Flat puzzle' described below.


Not 100% sure what you want, but this stylesheet illustrates
a way to get the basic result you're looking for. Given
an input document like:

<LIST>
  <A>content</A>
  <B dep="A">content</B>
  <C dep="B">content</C>
  <D/>
  <E dep="nowhere"/>
  <X>content</X>
  <Y dep="X">content</Y>
  <Z dep="Y">content</Z>
  <Q dep="C">content</Q>
</LIST>

It produces:

<html>
   <body>
      <h2>A B C Q</h2>
      <ol>
         <li>A</li>
         <li>B</li>
         <li>C</li>
         <li>Q</li>
      </ol>
      <!--
       | wasn't sure if you wanted
       | something with no deps to show
       | as the only thing under it's heading
       | or to not have anything show...
       +>
      <h2>D</h2>
      <ol>
         <li>D</li>
      </ol>
      <h2>X Y Z</h2>
      <ol>
         <li>X</li>
         <li>Y</li>
         <li>Z</li>
      </ol>
   </body>
</html>

Here's the stylesheet. With some minor tweaking it
should be able to be coaxed into what you're looking
for. At the moment it's not picking up the <E/> element
but this could be done, too, with a little more work.
Just wanted to show the basic idea. I initially 
developed it with the OracleXSL engine, but then 
later changed the 'ora' prefix to map to the Saxon
namespace and tested it with Saxon, too.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:ora="http://icl.com/saxon";
                exclude-result-prefixes="ora">
  <xsl:output method="html"/>
  <!-- Index <LIST> children by their dep attribute for fast lookups -->
  <xsl:key name="dep" match="LIST/*" use="@dep"/>
  <xsl:template match="LIST">
    <html>
      <body>
        <!-- For each LIST child element with no dep attribute -->
        <xsl:for-each select="*[not(@dep)]">
          <!-- Collect dependency chain for current element into a variable -->
          <xsl:variable name="deps">
            <xsl:call-template name="selfdeps">
              <xsl:with-param name="n" select="."/>
            </xsl:call-template>
          </xsl:variable>
          <!-- Convert result tree fragment into nodeset for processing -->
          <xsl:variable name="deps-set" select="ora:node-set($deps)"/>
          <!-- Create space-separated title for the header -->
          <xsl:variable name="title">
            <xsl:for-each select="$deps-set/*">
              <xsl:value-of select="name(.)"/>
              <xsl:if test="position()!=last()">
                <xsl:text> </xsl:text>
              </xsl:if>
            </xsl:for-each>
          </xsl:variable>
          <!-- Print the header -->
          <h2><xsl:value-of select="$title"/></h2>
          <!-- Print the list of dependencies including initial element -->
          <ol>
          <xsl:for-each select="$deps-set/*">
            <li><xsl:value-of select="name(.)"/></li>
          </xsl:for-each>
          </ol>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="selfdeps">
    <xsl:param name="n"/>
    <!-- Copy the current element into the result tree fragment -->
    <xsl:copy-of select="$n"/>
    <!-- If there are some dependencies, recurse to copy them -->
    <xsl:if test="count(key('dep',name($n)))>0">
      <xsl:call-template name="selfdeps">
        <xsl:with-param name="n" select="key('dep',name($n))[1]"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>
______________________________________________________________
Steve Muench, Lead XML Evangelist & Consulting Product Manager
BC4J & XSQL Servlet Development Teams, Oracle Rep to XSL WG
Author "Building Oracle XML Applications", O'Reilly
http://www.oreilly.com/catalog/orxmlapp/





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


Current Thread