xsl-list
[Top] [All Lists]

Re: [xsl] Newbie Question: Convert "flat" hierarchy to nested hierarchy

2006-10-15 03:29:07
Here's a quick and dirty method to convert your flat sample to nested hierarchy. I didn't copy all the supposed markup here, just created the hierarchy. My source file was:

<?xml version='1.0' encoding='utf-8'?>
<text>
   <flat lvl="1"> {markupA} </flat>
   <flat lvl="2"> {markupB} </flat>
   <flat lvl="2"> {markupC} </flat>
   <flat lvl="1"> {markupD} </flat>
   <flat lvl="2"> {markupE} </flat>
   <flat lvl="2"> {markupF} </flat>
   <flat lvl="3"> {markupG} </flat>
   <flat lvl="4"> {markupH} </flat>
   <flat lvl="4"> {markupI} </flat>
   <flat lvl="3"> {markupJ} </flat>
   <flat lvl="3"> {markupK} </flat>
   <flat lvl="2"> {markupL} </flat>
   <flat lvl="1"> {markupM} </flat>
</text>

The XSLT is:

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/ Transform'>

<xsl:output method='xml' version='1.0' encoding='utf-8' indent='yes'/>

<xsl:template match="/">
  <xsl:call-template name="nest">
    <xsl:with-param name="flat" select="text/flat[1]" />
  </xsl:call-template>
</xsl:template>

<xsl:template name="nest">
  <xsl:param name="flat" />
  <xsl:element name="nest">
    <xsl:value-of select="$flat" />
    <xsl:if test="$flat/following::flat[1]/@lvl &gt; $flat/@lvl">
      <xsl:call-template name="nest">
<xsl:with-param name="flat" select="$flat/following::flat [1]" />
      </xsl:call-template>
    </xsl:if>
  </xsl:element>
<xsl:variable name="next" select="$flat/following::flat[(_at_)lvl &lt;= $flat/@lvl]" />
  <xsl:if test="$next[1]/@lvl = $flat/@lvl">
    <xsl:call-template name="nest">
      <xsl:with-param name="flat" select="$next[1]" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Kind regards,
--
Mikhail Edoshin
m(_dot_)edoshin(_at_)mac(_dot_)com

On Oct 14, 2006, at 8:28 PM, Watch-O-Matic wrote:

Michael Kay wrote:

You'll find a paper that tackles this problem (using XSLT 2.0) at

http://www.idealliance.org/proceedings/xml04/papers/111/mhk- paper.html

The reverse transformation is much easier: you just process all the
elements in document order (//nest) and for each one compute its
level number as count(ancestor::*).

Thank you for your prompt answer.

Since I am a newbie at this, it'll take me a while to understand your
paper (and XSLT in general.) But I assume from your reply that the
transformation from 'flat' to 'nested' (which is of most interest to
me at the moment) is doable with XSLT 2.0.

Of course, would love to see an XSLT 2.0 transformation specific to
the 'flat' to 'nested' example, if someone here has the interest --
and a moment to spare. That will greatly help. It also seems "generic"
enough that the transformation may be useful to someone else in the
future.

Again, much thanks.

Mark
--
  Watch-O-Matic
  watchomatic(_at_)fastmail(_dot_)fm

--
http://www.fastmail.fm - Same, same, but different…


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