Render XML structure using XSLT

S

Sylvia

Hi,
I'm trying to render a XML structure to HTML using XSLT.
My XML describe the header of a table with a complex and not linear
structure.
The first row of the header table always contains the ServiceName
(attribute name), under I have to show all the other fields with
correct structure.
Can you help me to write XSLT document?

My XML doc:
******************************************************************************
<?xml version="1.0" encoding="UTF-8"?>
<data>
<Service depth="6" name="service1" totalDepth="2">
<Field depth="0" name="1.1"/>
<Field depth="0" name="1.2"/>
<Field depth="0" name="1.3"/>
<Field depth="0" name="1.4"/>
<Field depth="0" name="1.5"/>
<Field depth="0" name="1.6"/>
</Service>
<Service depth="8" name="service2" totalDepth="4">
<Field depth="4" name="2.1">
<Field depth="4" name="2.1.1">
<Field depth="0" name="2.1.1.1"/>
<Field depth="0" name="2.1.1.2"/>
<Field depth="0" name="2.1.1.3"/>
<Field depth="0" name="2.1.1.4"/>
</Field>
<Field depth="4" name="2.1.2">
<Field depth="0" name="2.1.2.1"/>
<Field depth="0" name="2.1.2.2"/>
<Field depth="0" name="2.1.2.3."/>
<Field depth="0" name="2.1.2.4"/>
</Field>
<Field depth="4" name="2.1.3.">
<Field depth="0" name="2.1.3.1"/>
<Field depth="0" name="2.1.3.2"/>
<Field depth="0" name="2.1.3.3"/>
<Field depth="0" name="2.1.2.4"/>
</Field>
<Field depth="4" name="2.1.4">
<Field depth="0" name="2.1.4.1"/>
<Field depth="0" name="2.1.4.2"/>
<Field depth="0" name="2.1.4.3"/>
<Field depth="0" name="2.1.4.4"/>
</Field>
</Field>
<Field depth="4" name="2.2">
<Field depth="0" name="2.2.1"/>
<Field depth="0" name="2.2.2"/>
<Field depth="0" name="2.2.3"/>
<Field depth="0" name="2.2.4"/>
</Field>
</Service>
</data>

This is what I want to obtain:
******************************************************************************
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My Doc</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
</head>
<body>
<table border="1" cellpadding="0" cellspacing="0">
<tr align="center">
<td colspan="6">service1</td>
<td colspan="20">service2</td>
</tr>
<tr>
<td rowspan="3">1.1</td>
<td rowspan="3">1.2</td>
<td rowspan="3">1.3</td>
<td rowspan="3">1.4</td>
<td rowspan="3">1.5</td>
<td rowspan="3">1.6</td>
<td colspan="16">2.1</td>
<td colspan="4" rowspan="2">2.2</td>
</tr>
<tr>
<td colspan="4">2.1.1</td>
<td colspan="4">2.1.2</td>
<td colspan="4">2.1.3</td>
<td colspan="4">2.1.4</td>
</tr>
<tr>
<td>2.1.1.1</td>
<td>2.1.1.2</td>
<td>2.1.1.3</td>
<td>2.1.1.4</td>
<td>2.1.2.1</td>
<td>2.1.2.2</td>
<td>2.1.2.3.</td>
<td>2.1.2.4</td>
<td>2.1.3.1</td>
<td>2.1.3.2</td>
<td>2.1.3.3</td>
<td>2.1.2.4</td>
<td>2.1.4.1</td>
<td>2.1.4.2</td>
<td>2.1.4.3</td>
<td>2.1.4.4</td>
<td>2.2.1</td>
<td>2.2.2</td>
<td>2.2.3</td>
<td>2.2.4</td>
</tr>
</table>
</body>
</html>

Thanks.
 
J

Janwillem Borleffs

Sylvia said:
I'm trying to render a XML structure to HTML using XSLT.
My XML describe the header of a table with a complex and not linear
structure.
The first row of the header table always contains the ServiceName
(attribute name), under I have to show all the other fields with
correct structure.
Can you help me to write XSLT document?

The following might be helpful:

<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:eek:utput
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
method="html" indent="yes" />

<xsl:template match="data">
<html>
<head>
<title>My Doc</title>
</head>
<body>
<table border="1" cellpadding="0" cellspacing="0">
<tr align="center">
<xsl:apply-templates select="Service" />
</tr>
<tr>
<xsl:apply-templates select="Service/Field" />
</tr>
<tr>
<xsl:apply-templates select="Service/Field/Field[child::*]" />
</tr>
<tr>
<xsl:apply-templates select="child::Service/Field/Field/Field" />
<xsl:apply-templates select="Service/Field/Field[not(child::*)]" />
</tr>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="Service">
<td colspan="{count(descendant-or-self::Field[@depth='0'])}">
<xsl:value-of select="@name" />
</td>
</xsl:template>

<xsl:template match="Service/Field">
<td>
<xsl:call-template name="colspan" />
<xsl:call-template name="rowspan" />
<xsl:value-of select="@name" />
</td>
</xsl:template>

<xsl:template match="Service/Field/Field[child::*]">
<td>
<xsl:call-template name="colspan" />
<xsl:value-of select="@name" />
</td>
</xsl:template>

<xsl:template match="child::Service/Field/Field/Field">
<td>
<xsl:value-of select="@name" />
</td>
</xsl:template>

<xsl:template match="Service/Field/Field[not(child::*)]">
<td>
<xsl:value-of select="@name" />
</td>
</xsl:template>

<xsl:template name="colspan">
<xsl:if test="count(descendant::Field/Field) &gt; 1
or count(descendant::Field) &gt; 1">
<xsl:attribute name="colspan">
<xsl:choose>
<xsl:when test="count(descendant::Field/Field) &gt; 1">
<xsl:value-of select="count(descendant::Field/Field)" />
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="count(descendant::Field)" />
</xsl:eek:therwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
</xsl:template>

<xsl:template name="rowspan">
<xsl:if test="not(descendant::Field) or (. = //Service[2]/Field[2])">
<xsl:attribute name="rowspan">
<xsl:choose>
<xsl:when test="not(descendant::Field)">
<xsl:value-of select="count(ancestor-or-self::*)" />
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="count(ancestor::*)" />
</xsl:eek:therwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
</xsl:template>

</xsl:stylesheet>



JW
 
S

Sylvia

Great, but I have other a problem: if I add this following service, the
xslt doesn't work well
----------------------------------------------------------------------------------------------------------------------
<Service name="service3" depth="2" totalDepth="3">
<Field name="3.1" depth="2">
<Field name="3.1.1" depth="0"/>
<Field name="3.1.2" depth="0"/>
</Field>
<Field name="3.2" depth="2">
<Field name="3.2.1" depth="0"/>
<Field name="3.2.2" depth="0"/>
</Field>
</Service>

My XML document has a dynamic structure with unlimited number of
Service node, Field node and Field subnode.
The xslt document work only on a fix structure with maximum 3 level of
Field node.
XML dcoument has 2 different attribute:
- depth: is the number of child (without subnode) for the selected node
(i.e. "service3" has 2 child: "3.1" and "3.2")
- totalDepth: is the maximum deep of Service node. "service3" as
totalDepth="3": Service node + Field node + Field subnode

I think that these attributes can help you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top