<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*" />
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="root">
<ul>
<xsl:apply-templates select="row[not(ParentID)]" />
</ul>
</xsl:template>
<xsl:template match="row">
<xsl:variable name="this-id" select="ID" />
<xsl:choose>
<xsl:when test="count(following-sibling::row[ParentID = $this-id]) >
0">
<li><xsl:value-of select="Name"/>
<ul>
<xsl:apply-templates select="following-sibling::row[ParentID =
$this-id]" />
</ul>
</li>
</xsl:when>
<xsl:otherwise>
<li><xsl:value-of select="Name"/></li>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="ID" />
<xsl:template match="Name" />
<xsl:template match="ParentID" />
</xsl:stylesheet>
--
Charles Knell
cknell(_at_)onebox(_dot_)com - email
-----Original Message-----
From: Simon Shutter <simon(_at_)schemax(_dot_)com>
Sent: Fri, 16 Mar 2007 10:36:14 -0700
To: <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Subject: [xsl] Variation on adjaceny list question
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>
--~--
--~------------------------------------------------------------------
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>
--~--