xsl-list
[Top] [All Lists]

[xsl] Variation on adjaceny list question

2007-03-16 11:36:54


A few weeks ago I presented a problem in which I needed to transform a
tabular data set into a hierarchical set.  I then reframed my question
slightly to that the input is an XML representation of an adjacency list
where each <row> element has 0 or 1 parent element where the ParentID
element points to the ID element of the parent.

Sergey Dubinets provided a solution on the MSDN newsgroup that looks like
this.

For an input of :

<root>
  <row><ID>1</ID><Name>One</Name></row>
  <row><ID>2</ID><ParentID>1</ParentID><Name>Two</Name></row>
  <row><ID>3</ID><ParentID>2</ParentID><Name>Three</Name></row>
  <row><ID>4</ID><ParentID>1</ParentID><Name>Four</Name></row>
</root>

Use this stylesheet : 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
  <xsl:output
  version="1.0"
  indent="yes"
  omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>Tree</title>
      </head>
      <body>
        <xsl:apply-templates select="root/row[not(ParentID)]"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="row">
    <ul>
      <li>
        <xsl:value-of select="Name"/>
        <xsl:variable name="id" select="ID"/>
        <xsl:apply-templates select="../row[ParentID = $id]"/>
      </li>
    </ul>
  </xsl:template>

</xsl:stylesheet>

To produce this output :

<html>
  <head>
    <title>Tree</title>
  </head>
  <body>
    <ul>
 
<li>One<ul><li>Two<ul><li>Three</li></ul></li></ul><ul><li>Four</li></ul></l
i>
    </ul>
  </body>
</html>

However, what if I have more than one node (eg IDs 1 and 3) without a
ParentID like this:

<root>
  <row><ID>1</ID><Name>One</Name></row>
  <row><ID>2</ID><ParentID>1</ParentID><Name>Two</Name></row>
  <row><ID>3</ID><Name>Three</Name></row>
  <row><ID>4</ID><ParentID>3</ParentID><Name>Four</Name></row>
</root>

The stylesheet produces :

<html>
  <head>
    <title>Tree</title>
  </head>
  <body>
    <ul>
      <li>One<ul><li>Two</li></ul></li>
    </ul>
    <ul>
      <li>Three<ul><li>Four</li></ul></li>
    </ul>
  </body>
</html>

My question is - how can I change the stylesheet such that the two unordered
lists are combined to produce this desired output:

<html>
  <head>
    <title>Tree</title>
  </head>
  <body>
    <ul>
      <li>One<ul><li>Two</li></ul></li>
      <li>Three<ul><li>Four</li></ul></li>
    </ul>
  </body>
</html>


Thanks, Simon


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