xsl-list
[Top] [All Lists]

Re: [xsl] XSLT 1: From flat XML to tree hierarchy XML. Can't seem to find the right way to do it.

2006-05-25 09:30:27

I'm afraid I'm not following what you want done with the namespaces,
but in general I think that if you are stuck doing this in XSLT 1.0
you can achieve your goal of emitting a tree from a flat list by using
the Muenchian grouping technique:

  http://www.jenitennison.com/xslt/grouping/muenchian.html

I'm dashing this off before I head to work, so apologies if it isn't
as complete as you spec out.  I *think* it does what you want in terms
of the tree structure.  Apologies if I've misunderstood what you are
after!

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0" 
xmlns:abel="http://something.com";>

  <xsl:output indent="yes" />

  <!-- table-by-category lets us look up all tableName elements matching a 
category -->
  <xsl:key name="table-by-category" match="abel:tableName" use="@category-name" 
/>

  <!-- 
    At the root of our output tree emit the tableName for 'Root'
  -->
  <xsl:template match="/">
    <xsl:element name="abel:tree">
      <xsl:attribute name="id">0</xsl:attribute>

      <!-- process the first tableName with a category-name matching 'Root' -->
      <xsl:apply-templates 
select="//abel:tableName[(_at_)category-name='Root'][1]" />
    </xsl:element>
  </xsl:template>

  <!-- 
    Process each 1st tableName by emitting an item and
    then processing its descendents and then its children.
  -->
  <xsl:template 
match="abel:tableName[generate-id(.)=generate-id(key('table-by-category', 
@category-name)[1])]">
    <xsl:element name="abel:item">

      <xsl:attribute name="text">
        <xsl:value-of select="string(.)" />
      </xsl:attribute>

      <xsl:attribute name="id">
        <xsl:choose>
          <xsl:when test="@id">
            <xsl:value-of select="@id" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@category-name" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>

      <!-- process each 1st tableName which has a parent-category-name matching 
our category-name -->
      <xsl:apply-templates select="//abel:tableName
                  [(_at_)category-parent-name=current()/@category-name]
                  [generate-id(.)=generate-id(key('table-by-category', 
@category-name)[1])]" />

      <!-- process all other tableName entries with the same category-name -->
      <xsl:apply-templates 
select="key('table-by-category',@category-name)[position() != 1]" />

    </xsl:element>
  </xsl:template>

  <!--
    Catch-all rule to emit an item for each tableName, not processing
    any children or siblings.
  -->
  <xsl:template match="abel:tableName">
    <xsl:element name="abel:item">

      <xsl:attribute name="text">
        <xsl:value-of select="string(.)" />
      </xsl:attribute>

      <xsl:attribute name="id">
        <xsl:choose>
          <xsl:when test="@id">
            <xsl:value-of select="@id" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@category-name" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>

    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson                       
jim(_dot_)robinson(_at_)stanford(_dot_)edu
Stanford University HighWire Press      http://highwire.stanford.edu/
+1 650 7237294 (Work)                   +1 650 7259335 (Fax)

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