Reputation: 1
It has been awhile since I coded, and a friend has asked me for help. I can't seem to get my head around it. It's old code I'm trying to fix up.
Basically, I'm trying to make a table that indents for each child of the parent.
I can get it to indent the first child correctly, then it stops. Can someone kindly point in the direction of where I can read up on this?
*Update
I have added code as best as I can atm. Adding during break at work. Will update more if needed after work.
Data - Values have been changes because I've been feeling snackish.
<foods>
<name>Junk Food</name>
<qty>1</qty>
<children>
<food>
<name>Gummies</name>
<qty>7</qty>
<children>
<food>
<name>Chocolate</name>
<qty>5</qty>
<children />
</food>
</children>
<children>
<food>
<name>Sour</name>
<qty>2</qty>
<children />
</food>
</children>
<food>
<name>Chips</name>
<qty>8</qty>
<children>
<food>
<name>Salt & Vinegar</name>
<qty>5</qty>
<children />
</food>
<food>
<name>Lightly Salted</name>
<qty>1</qty>
<children>
<food>
<name>Rippled</name>
<qty>2</qty>
<children>
</food>
</children>
</food>
<children />
</food>
<food>
<name>Fruit</name>
<qty>18</qty>
<children>
<food>
<name>Pineapple</name>
<qty>5</qty>
<children />
</food>
<food>
<name>Apple</name>
<qty>13</qty>
<children>
<food>
<name>Macintosh</name>
<qty>8</qty>
<children />
</food>
<food>
<name>Golden</name>
<qty>2</qty>
<children />
</food>
<food>
<name>Granny Smith</name>
<qty>3</qty>
<children />
</food>
</children>
</food>
</children>
</food>
</children>
</foods>
**Code **
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Character sheet based on the Shadowrun 4th Edition Character Sheet -->
<!-- Created by Keith Rudolph, [email protected] -->
<!-- Version -892 -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:include href="ConditionMonitor.xslt"/>
<xsl:template match="/characters/character">
<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">]]></xsl:text>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title><xsl:value-of select="name" /></title>
<style type="text/css">
*
{
font-family: segoe condensed, tahoma, trebuchet ms, arial;
font-size: 8pt;
text-align: left;
}
.tableborder
{
border: solid 2px #1c4a2d;
}
.indent
{
padding-left: 20px;
}
</style>
</head>
<body>
<div class="block" id="foodBlock">
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr><td width="70%" class="tableborder" style="text-align:center;" valign="top">
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="55%">
<strong>NAME</strong>
</td>
<td width="15%" style="text-align:center;">
<strong>QTY.</strong>
</td>
</tr>
<xsl:call-template name="food1" />
</table>
</td>
</tr>
</table>
</div>
<xsl:template name="foodplugin">
<xsl:param name="food" />
<xsl:for-each select="children/food">
<xsl:sort select="name" />
<xsl:sort select="foodname" />
<xsl:value-of select="qty" /><xsl:text>x </xsl:text>
<xsl:value-of select="name" />
<xsl:if test="children/food">
<br /><xsl:text>  </xsl:text>
<xsl:call-template name="foodplugin">
<xsl:with-param name="food" select="." />
</xsl:call-template>
</xsl:if>
<xsl:if test="position() != last()"><br /></xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="food1">
<xsl:variable name="halfcut" select="count(foods/food)"/>
<xsl:variable name="sortedcopy">
<xsl:for-each select="foods/food">
<xsl:sort select="food" />
<xsl:sort select="name" />
<xsl:if test="position() <= $halfcut">
<xsl:copy-of select="current()"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="msxsl:node-set($sortedcopy)/food">
<xsl:choose>
<xsl:when test="position() = 1">
<tr><td colspan="3" style="border-bottom:solid black 1px;"><strong><xsl:value-of select="location" /></strong></td></tr>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="location != preceding-sibling::food[1]/location">
<tr><td colspan="3" style="border-bottom:solid black 1px;"><strong><xsl:value-of select="location" /></strong></td></tr>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<tr>
<xsl:if test="position() mod 2 != 1">
<xsl:attribute name="bgcolor">#e4e4e4</xsl:attribute>
</xsl:if>
<td width="80%" valign="top">
<xsl:value-of select="name" />
</td>
<td width="10%" style="text-align:center;" valign="top">
<xsl:choose>
<xsl:when test="children/food != ''"> </xsl:when>
<xsl:otherwise><xsl:value-of select="qty" /></xsl:otherwise>
</xsl:choose>
</td>
</tr>
<xsl:if test="children/food">
<tr>
<xsl:if test="position() mod 2 != 1">
<xsl:attribute name="bgcolor">#e4e4e4</xsl:attribute>
</xsl:if>
<td colspan="3" class="indentfood">
<xsl:call-template name="foodplugin">
<xsl:with-param name="food" select="." />
</xsl:call-template>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</body>
</html>
</xsl:template>
Desired
Gummies
Chocolate
Sour
Chips
Salt & Vinegar
Lightly Salted
Rippled
Fruit
Pineapple
Apple
Granny Smith
BC
California
Golden
Macintosh
Result
Gummies
Chocolate
Sour
Chips
Salt & Vinegar
Lightly Salted
Rippled
Fruit
Pineapple
Apple
Granny Smith
BC
California
Golden
Macintosh
Upvotes: 0
Views: 49
Reputation: 116959
Here is an even simpler stylesheet that produces a text result indented by tab characters. This also uses XSLT's native recursion to increase the indent at each level.
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="food">
<xsl:param name="indent"/>
<xsl:value-of select="$indent"/>
<xsl:value-of select="name"/>
<xsl:text> </xsl:text>
<xsl:apply-templates select="children/food">
<xsl:with-param name="indent" select="concat($indent, '	')"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
Using the same XML example input as in my previous answer, the result here will be:
Junk Food
Gummies
Chocolate
Sour
Chips
Salt & Vinegar
Lightly Salted
Rippled
Fruit
Pineapple
Apple
Macintosh
Golden
Granny Smith
Upvotes: 0
Reputation: 116959
Here is a simple stylesheet that uses XSLT's recursive processing model to produce a nested HTML unordered list:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/ | children">
<ul>
<xsl:apply-templates select="food"/>
</ul>
</xsl:template>
<xsl:template match="food">
<li>
<xsl:value-of select="name"/>
<xsl:apply-templates select="children"/>
</li>
</xsl:template>
</xsl:stylesheet>
Given a well-formed (!!!) XML input:
<food>
<name>Junk Food</name>
<qty>1</qty>
<children>
<food>
<name>Gummies</name>
<qty>7</qty>
<children>
<food>
<name>Chocolate</name>
<qty>5</qty>
<children />
</food>
<food>
<name>Sour</name>
<qty>2</qty>
<children />
</food>
</children>
</food>
<food>
<name>Chips</name>
<qty>8</qty>
<children>
<food>
<name>Salt & Vinegar</name>
<qty>5</qty>
</food>
<food>
<name>Lightly Salted</name>
<qty>1</qty>
<children>
<food>
<name>Rippled</name>
<qty>2</qty>
<children/>
</food>
</children>
</food>
</children>
</food>
<food>
<name>Fruit</name>
<qty>18</qty>
<children>
<food>
<name>Pineapple</name>
<qty>5</qty>
<children />
</food>
<food>
<name>Apple</name>
<qty>13</qty>
<children>
<food>
<name>Macintosh</name>
<qty>8</qty>
<children/>
</food>
<food>
<name>Golden</name>
<qty>2</qty>
<children/>
</food>
<food>
<name>Granny Smith</name>
<qty>3</qty>
<children/>
</food>
</children>
</food>
</children>
</food>
</children>
</food>
the (rendered) result will be:
You can add CSS code to further style the result.
Upvotes: 0