basically what i want to do right now is to display items from a specific tag. I am planning to differentiate the tags with unique attribute. The problem i facing right now is that i doesnt seem to be working as it is still displaying items from another tag. Please help.
This is the XML content
<group name="Personal Particulars">
<field is_admin_field="N" required="Y">
<question_title>Name</question_title>
<type>TextField</type>
<db_field_name>name</db_field_name>
<db_field_length>250</db_field_length>
<db_field_type>string</db_field_type>
<additional_comment/>
</field>
<field is_admin_field="N" required="Y">
<question_title>NRIC/FIN</question_title>
<type>TextField</type>
<db_field_name>nricfin</db_field_name>
<db_field_length>20</db_field_length>
<db_field_type>string</db_field_type>
<additional_comment/>
</field>
<field is_admin_field="N" required="Y">
<question_title>Contact No.</question_title>
<type>TextField</type>
<db_field_name>contact_no</db_field_name>
<db_field_length>20</db_field_length>
<db_field_type>string</db_field_type>
<additional_comment/>
</field>
</group>
<group name="Housing Type">
<field is_admin_field="N" required="Y">
<question_title>Which of the housing type best describes your residential?</question_title>
<type>List</type>
<db_field_name>which_of_the_housing_type_best_describes_your_residential</db_field_name>
<options>
<item score="0">3 - 5 room HDB</item>
<item score="0">Executive Condominium </item>
<item score="0">Landed 1 Floor</item>
<item score="0">Landed 2 Floor</item>
<item score="0">Landed 3 Floor</item>
<item score="0">Landed 4 Floor</item>
<item score="0">Landed 5 Floor</item>
</options>
<db_field_length>22</db_field_length>
<additional_comment/>
</field>
</group>
This is the XSLT
<div style="border:1px solid black">
<div style="border:1px solid black">
<xsl:variable name="name" select="/form/fieldset/group/#name"/>
<xsl:if test="$name='Personal Particulars'">
<xsl:text>Personal Particulars</xsl:text>
<xsl:for-each select="form/fieldset/group/field">
<div>
<xsl:value-of select="question_title"/>
</div>
<xsl:variable name="type" select="type"/>
<xsl:if test="$type='TextField'">
<xsl:element name="input">
<xsl:attribute name="type">textbox</xsl:attribute>
<xsl:attribute name="maxlength">5</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:if>
</div>
<div style="border:1px solid black">
<xsl:variable name="name" select="/form/fieldset/group/#name"/>
<xsl:if test="$name='Housing Type'">
<xsl:text>Housing Type</xsl:text>
<xsl:for-each select="form/fieldset/group/field">
<div>
<xsl:value-of select="form/fieldset/group/question_title"/>
</div>
<xsl:variable name="type" select="type"/>
<xsl:if test="$type='TextField'">
<xsl:element name="input">
<xsl:attribute name="type">textbox</xsl:attribute>
<xsl:attribute name="maxlength">5</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:if>
</div>
</div>
Try this. You will have to adjust the XPath in for-each loops to match the actual XML structure-
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" encoding="utf-8" indent="yes" />
<xsl:template match="/">
<xsl:for-each select="item">
<div style="font-size:150%;margin-top:5%;">
<xsl:value-of select="title"/>
</div>
<div style="font-size:150%;">
<xsl:value-of select="description"/>
</div>
<xsl:variable name="category" select="category"/>
<xsl:if test= "$category = 'Text' " >
<xsl:for-each select="./options/need">
<div>
<xsl:element name="input">
<xsl:attribute name="type">checkbox</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="need"/>
</xsl:attribute>
</xsl:element>
<label>
<xsl:value-of select="."/>
</label>
</div>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
OUTPUT-
Having a variable like <xsl:variable name="category" select="category"/> will give you the ability to put the conditional <xsl:if test= "$category = 'Text' " > anywhere you want within the nested for-each loops
As per the follow-up comment, adding how to display radio buttons-
<xsl:element name="input">
<xsl:attribute name="type">radio</xsl:attribute>
<xsl:attribute name="name">something</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="need"/>
</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>
<label>
<xsl:value-of select="."/>
</label>
From the following xml data:
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="kandidaten.xsl" type="text/xsl"?>
<auswertung>
<kandidat>
<name>Peter</name>
<punkte>67</punkte>
</kandidat>
<kandidat>
<name>Karl</name>
<punkte>87</punkte>
</kandidat>
<kandidat>
<name>Anita</name>
<punkte>36</punkte>
</kandidat>
<kandidat>
<name>Rosi</name>
<punkte>67</punkte>
</kandidat>
<kandidat>
<name>Heiner</name>
<punkte>50</punkte>
</kandidat>
<kandidat>
<name>Paul</name>
<punkte>45</punkte>
</kandidat>
</auswertung>
I want to create the following output with xslt:
To this end I wrote the following xslt code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="auswertung">
<html>
<head>
<title>Kandidaten</title>
</head>
<body>
<h1>Kandidaten und ihre Punkte</h1>
<hr/>
<table>
<xsl:apply-templates select="kandidat">
<xsl:sort select="punkte" order="descending"></xsl:sort>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="kandidat">
<tr>
<td>
<xsl:value-of select="name/text()"/>
</td>
<!-- second columns of table is supposed to contain the -->
<!-- points ("punkte") of the respective candidate ("kandidat") -->
<td>
<!-- second column contains a paragraph whose background-color is blue -->
<p bgcolor="#0000ff">
<xsl:call-template name="create_empty_space">
<xsl:with-param name="count" select="punkte/text()"/>
<xsl:with-param name="number" select="punkte/text()"/>
</xsl:call-template>
</p>
</td>
</tr>
</xsl:template>
<xsl:template name="create_empty_space">
<xsl:param name="count"/>
<xsl:param name="number"/>
<!-- print number (points achieved by candidate) in the middle of the beam -->
<xsl:if test="$count = round($number div 2)">
<font color="#ffff00">
<xsl:value-of select="$number"/>
</font>
</xsl:if>
<xsl:if test="$count > 0">
<!-- amount of empty space created is supposed to depend on the number of -->
<!--points, therefore function "create_empty_space" is called recursively-->
<!-- depending on the number of points -->
<!--... example: if points==20, function is called 20 times -->
<xsl:text> </xsl:text>
<xsl:call-template name="create_empty_space">
<xsl:with-param name="count" select="$count - 1"/>
<xsl:with-param name="number" select="$number"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When I run the code, all beams have the same size, though.
How can I make the length of the beams correspond to the number of points of the respective candidate?
Since you're using xml-stylesheet in your XML input, I doubt you're really using a 2.0 processor.
Like Martin suggested, the first items width should be 100% and the width of the remaining items should be computed based on the first (max).
Here's a modified version of your XSLT...
XSLT 1.0
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<!--This is easier in XSLT 2.0:
<xsl:variable name="maxPoints" select="max(/*/kandidat/punkte)"/>
-->
<xsl:variable name="maxPoints">
<xsl:for-each select="/*/kandidat">
<xsl:sort select="punkte" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="punkte"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="auswertung">
<html>
<head>
<title>Kandidaten</title>
</head>
<body>
<h1>Kandidaten und ihre Punkte</h1>
<hr/>
<table style="width: 100%">
<xsl:apply-templates select="kandidat">
<xsl:sort select="punkte" order="descending"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="kandidat">
<tr>
<td style="width: 1%">
<xsl:value-of select="name"/>
</td>
<!-- second columns of table is supposed to contain the -->
<!-- points ("punkte") of the respective candidate ("kandidat") -->
<td>
<!-- second column contains a paragraph whose background-color is blue -->
<div style="text-align: center;width: {round(punkte div $maxPoints * 100)}%;color: #ffff00;background-color: #0000ff;">
<xsl:value-of select="punkte"/>
</div>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
Output
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Kandidaten</title>
</head>
<body>
<h1>Kandidaten und ihre Punkte</h1>
<hr>
<table style="width: 100%">
<tr>
<td style="width: 1%">Karl</td>
<td>
<div style="text-align: center;width: 100%;color: #ffff00;background-color: #0000ff;">87</div>
</td>
</tr>
<tr>
<td style="width: 1%">Peter</td>
<td>
<div style="text-align: center;width: 77%;color: #ffff00;background-color: #0000ff;">67</div>
</td>
</tr>
<tr>
<td style="width: 1%">Rosi</td>
<td>
<div style="text-align: center;width: 77%;color: #ffff00;background-color: #0000ff;">67</div>
</td>
</tr>
<tr>
<td style="width: 1%">Heiner</td>
<td>
<div style="text-align: center;width: 57%;color: #ffff00;background-color: #0000ff;">50</div>
</td>
</tr>
<tr>
<td style="width: 1%">Paul</td>
<td>
<div style="text-align: center;width: 52%;color: #ffff00;background-color: #0000ff;">45</div>
</td>
</tr>
<tr>
<td style="width: 1%">Anita</td>
<td>
<div style="text-align: center;width: 41%;color: #ffff00;background-color: #0000ff;">36</div>
</td>
</tr>
</table>
</body>
</html>
EDIT: You could also clean up your stylesheet and output a little by using CSS classes...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<!--This is easier in XSLT 2.0:
<xsl:variable name="maxPoints" select="max(/*/kandidat/punkte)"/>
-->
<xsl:variable name="maxPoints">
<xsl:for-each select="/*/kandidat">
<xsl:sort select="punkte" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="punkte"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="auswertung">
<html>
<head>
<title>Kandidaten</title>
<style type="text/css">
.name {
width: 10%;
}
.punkte {
text-align: center;
color: #ffff00;
background-color: #0000ff;
}
table.kandidat {
width: 100%;
}
</style>
</head>
<body>
<h1>Kandidaten und ihre Punkte</h1>
<hr/>
<table class="kandidat">
<xsl:apply-templates select="kandidat">
<xsl:sort select="punkte" order="descending"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="kandidat">
<tr>
<td class="name">
<xsl:value-of select="name"/>
</td>
<td>
<div style="width: {round(punkte div $maxPoints * 100)}%;"
class="punkte">
<xsl:value-of select="punkte"/>
</div>
</td>
</tr>
</xsl:template>
I have used font awesome icon in my project. The html page generate from XSL templates. After searching lots of question. I decided to add a meta tag at in head as first ta. but xsl alwys put a auto generate meta tag as follows-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<meta content="IE=9; IE=EDGE" http-equiv="X-UA-Compatible" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" href="css/jquery-ui.css?ver=T1.0" />
<link rel="stylesheet" type="text/css" href="css/font-awesome.min.css?ver=T1.0" />
<link rel="stylesheet" type="text/css" href="css/style.css?ver=T1.0" />
<link rel="SHORTCUT ICON" href="images/favicon.ico" />
</head>
<body>
</body>
My requirement is displaying Custom font and Font Awesome icon on IE9 & IE11 compatibility view. Currently Not display as stated.
So I want to try with putting X-UA-Compatible meta tag first tag.So How can I do this ? or how to fix that font awesome and custom font work properly IE9 & IE11 compatibility view?
Here is my XSL -
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>
<xsl:include href="portalheader.xsl"/>
<xsl:template match="data">
<xsl:if test="//ajax">
<xsl:apply-templates select="//ajax/*"/>
</xsl:if>
<xsl:if test="not(//ajax)">
<xsl:apply-templates select="//wp"/>
</xsl:if>
</xsl:template>
<xsl:template match="wp">
<html>
<head>
<xsl:if test="xua">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7; IE=EmulateIE9"/>
</xsl:if>
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="css/picdef.css?ver=T1.0" rel="stylesheet" type="text/css" media="screen"/>
<link href="css/jquery-ui.css?ver=T1.0" rel="stylesheet" media="screen" type="text/css"/>
<link href="css/print.css?ver=T1.0" rel="stylesheet" type="text/css" media="print" />
<link href="css/font-awesome.min.css?ver=T1.0" rel="stylesheet" type="text/css" media="screen"/>
<link href="css/style.css?ver=T1.0" rel="stylesheet" type="text/css" media="screen"/>
<link rel="SHORTCUT ICON" href="images/favicon.ico"/>
<xsl:for-each select="//style">
<link href="{.}" rel="stylesheet" type="text/css"/>
</xsl:for-each>
<xsl:call-template name="includejava"/>
<xsl:if test="not(popup)">
<xsl:call-template name="portalheader" />
</xsl:if>
</head>
<body>
<xsl:apply-templates select="#*"/>
<xsl:if test="not(frame)">
<xsl:call-template name="newpagetop"/>
<xsl:apply-templates select="page|popup"/>
</xsl:if>
.......................
..........................
..........................
</body>
</html>
</xsl:template>
<xsl:template name="includejava">
<script src="js/jquery/jquery-1.7.2.min.js?ver=T1.0" type="text/javascript"/>
<script src="js/jquery/jquery-ui-1.8.21.custom.min.js?ver=T1.0" type="text/javascript"/>
</xsl:template>
<xsl:template name="pagemenu">
<xsl:if test="menu">
<div class="pagebar" style="width:50%">
<div class="line">
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td class="mainmenu">
<xsl:apply-templates select="menu"/>
</td>
</tr>
</table>
</div>
</div>
</xsl:if>
</xsl:template>
<xsl:template match="content">
<div class="content">
<xsl:apply-templates select="*"/>
</div>
</xsl:template>
<xsl:template match="item">
<option title="{#title}">
<xsl:if test="#key">
<xsl:attribute name="value">
<xsl:value-of select="#key"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="not(#key)">
<xsl:attribute name="value">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="."/>
</option>
</xsl:template>
<xsl:template match="lable">
<lable>
<xsl:value-of select="."/>
</lable>
</xsl:template>
<xsl:template match="br">
<br/>
</xsl:template>
<xsl:template match="space">
<div style="height:5px;width:5px"/>
</xsl:template>
<xsl:template match="action">
<a>
<xsl:if test="not(#href)">
<xsl:attribute name="href">#</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="#*"/>
<xsl:value-of select="."/>
</a>
</xsl:template>
<xsl:template match="moveaction">
<a class="empty">
<xsl:apply-templates select="#*"/>
<img alt="drag" src="images/c.gif" class="dragdrop move but" style="margin-right:4px"/>
<xsl:value-of select="."/>
</a>
</xsl:template>
<xsl:template name="submit">
<input type="submit" class="submit" value="{.}">
<xsl:apply-templates select="#*"/>
</input>
</xsl:template>
<xsl:template match="submit">
<xsl:call-template name="submit"/>
</xsl:template>
<xsl:template match="submitbar">
<div class="submitbar">
<xsl:call-template name="submit"/>
<xsl:apply-templates select="*"/>
</div>
</xsl:template>
<xsl:template name="wrap">
<table cellpadding="0" cellspacing="0" style="table-layout:fixed;width:100%">
<tr>
<td nowrap="nowrap" style="overflow:hidden" title="{text()}">
<xsl:value-of select="text()"/>
</td>
</tr>
</table>
</xsl:template>
<xsl:template match="jscript">
<div >
<xsl:attribute name="class">
<xsl:value-of select="."/>
</xsl:attribute>
</div>
</xsl:template>
<xsl:template match="div">
<div>
<xsl:apply-templates select="#*"/>
<xsl:apply-templates select="*"/></div>
</xsl:template>
<xsl:template match="#*">
<xsl:choose>
<xsl:when test="#space">
<div style="height:5px;width:5px"/>
</xsl:when>
<xsl:when test="#java">
<xsl:apply-templates select="#java"/>
</xsl:when>
<xsl:when test="#href">
<xsl:call-template name="link"/>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="{name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="#javax">
<a href="javascript:" java="{.}">
<xsl:value-of select="../node()"/>
</a>
</xsl:template>
<xsl:template match="iframe">
<iframe frameBorder="0" width="100%" id="{#id}" class="{#class}">
<xsl:attribute name="addr">
<xsl:value-of select="."/>
</xsl:attribute>
</iframe>
</xsl:template>
<xsl:template match="#disabled">
<xsl:attribute name="disabled">disabled</xsl:attribute>
</xsl:template>
<xsl:template match="#id">
<xsl:attribute name="id">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="xmlhtml">
<xsl:call-template name="copy"/>
</xsl:template>
<xsl:template name="copy">
<xsl:for-each select="*"><xsl:copy>
<xsl:apply-templates select="#*"/><xsl:value-of select="."/>
<xsl:call-template name="copy"/>
</xsl:copy></xsl:for-each>
</xsl:template>
<xsl:template match="#mandatory">
<xsl:attribute name="mandatory">1</xsl:attribute>
</xsl:template>
<xsl:template match="ns">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>
I'm trying to achieve a tree view of an xml file using XSLT and css.
I have nested children in xml and I'm iterating through them to display content of each entry.
Each child is a logger with message entries. I would like to have each child table indented according to ancestor count which i get correctly. however trying to set the table margin dynamically margin-left="$margin*10" doesnot work.
This is my XSLT / xml
<xsl:template match="operationLogger">
<xsl:variable name="margin" select="count(ancestor::*) * 10"/>
<table class="normalTable" cols="4">
<xsl:attribute name="margin-left">
<xsl:value-of select="$margin"/>
</xsl:attribute>
<tr class="errorsCollectionTitle">
<td colspan="4">
<xsl:value-of select="#name"/>
</td>
</tr>
<xsl:if test="operationLogEntry">
<xsl:apply-templates select="operationLogEntry"/>
</xsl:if>
<xsl:if test="operationLogger">
<xsl:apply-templates select="operationLogger"/>
</xsl:if>
</table>
</xsl:template>
<xsl:template match="operationLogEntry">
<tr>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="position() mod 2 = 1">rowData</xsl:when>
<xsl:otherwise>rowAlternatingData</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="#level = 'Error'">errorImage</xsl:when>
<xsl:when test="#level = 'Warning'">warningImage</xsl:when>
<xsl:when test="#level = 'Info'">informationImage</xsl:when>
<xsl:when test="#level = 'Debug'">informationImage</xsl:when>
</xsl:choose>
</xsl:attribute>
</td>
<td class="timeStamp">
<xsl:value-of select="#timeStamp"/>
</td>
<td class="source">
<xsl:value-of select="../loggerSource/#computer" />
/
<xsl:value-of select="../loggerSource/#user" />
</td>
<td class="message">
<div>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="#level = 'Error'">errorColor</xsl:when>
<xsl:when test="#level = 'Warning'">warningColor</xsl:when>
<xsl:when test="#level = 'Info'">informationColor</xsl:when>
<xsl:when test="#level = 'Debug'">informationColor</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:value-of select="#message"/>
</div>
</td>
</tr>
</xsl:template>
<operationLogger name="">
<loggerSource domain="user" computer="computer" user="account" />
<operationLogEntry timeStamp="2015/02/16 07:15:21" level="Info" message="Adding 1 to transactions list" />
<operationLogEntry timeStamp="2015/02/16 07:15:21" level="Info" message="Executing 1 transactions..." />
<operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Executed 1 transactions successfully!" />
<operationLogger name="TransactionOperationCollection.Execute()">
<loggerSource domain="user" computer="computer" user="account" />
<operationLogEntry timeStamp="2015/02/16 07:15:21" level="Info" message="Commiting transaction 0:Transaction" />
<operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Committed transaction 0:Transaction" />
<operationLogger name="TransactionOperation.Commit()">
<operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Setting Auditonly" />
<operationLogEntry timeStamp="2015/02/16 07:15:22" level="Info" message="Succesfully changed Audit Only" />
</operationLogger>
</operationLogger>
</operationLogger>
and I tried looping from 1 to 'number of ancestors' and adding span or div. I tried pushing the content of the first row. nothing seems to work for me.
Any help would be greatly appreciated!
There is no such thing as a margin-left attribute. You can use a style attribute for this, though:
<xsl:attribute name="style">
<xsl:value-of select="concat('margin-left: ', $margin, 'px;')"/>
</xsl:attribute>
But using inline styles is rarely a good thing. I suggest you place your tables in a ul/li hierarchy. This way, you can put the margins in your CSS file/<style> section rather than calculating them dynamically:
<xsl:template match="/">
<ul>
<xsl:apply-templates />
</ul>
</xsl:template>
<xsl:template match="operationLogger">
<li>
<table class="normalTable" cols="4">
<tr class="errorsCollectionTitle">
<td colspan="4">
<xsl:value-of select="#name"/>
</td>
</tr>
<xsl:apply-templates select="operationLogEntry"/>
</table>
<xsl:if test="operationLogger">
<ul>
<xsl:apply-templates select="operationLogger"/>
</ul>
</xsl:if>
</li>
</xsl:template>
I would like to have the following XML:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<categories>
<name>Badges & Holders</name>
<value>1000111</value>
</categories>
<categories>
<name>Clips, Tacks & Rubber Bands</name>
<value>1000113</value>
</categories>
<categories>
<name>Clocks</name>
<value>1000114</value>
</categories>
<categories>
<name>Indexing Flags & Tabs</name>
<value>1000115</value>
</categories>
<categories>
<name>Magnification</name>
<value>1000116</value>
</categories>
<categories>
<name>Pad Holders</name>
<value>1000117</value>
</categories>
<categories>
<name>Paper Punch Accessories</name>
<value>1000118</value>
</categories>
<categories>
<name>Paper Punches</name>
<value>1000119</value>
</categories>
<categories>
<name>Scissors, Rulers & Paper Trimmers</name>
<value>1000120</value>
</categories>
<categories>
<name>Signs & Nameplates</name>
<value>1000121</value>
</categories>
<categories>
<name>Stamps & Pads Accessories</name>
<value>1000122</value>
</categories>
<categories>
<name>Stapler Accessories</name>
<value>1000123</value>
</categories>
<categories>
<name>Staplers</name>
<value>1000124</value>
</categories>
<categories>
<name>Tags & Tickets</name>
<value>1000125</value>
</categories>
<categories>
<name>Tape, Glue & Adhesives</name>
<value>1000126</value>
</categories>
</NewDataSet>
And turn it into HTML (table) like this:
<table>
<tr>
<td>
<div>
<img src="Path/" + {value} + ".jpg"></img>
</div>
<div>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name"/>
</span>
</div>
</td>
</tr>
</table>
Here is the kicker, though. I only need it to have 5 columns of TD's and then start over with a new TR after that.. all the way down. If it has, say, 12 items in the XML, then I need it to go ahead and have 15 TD's (I presume) so that the table is a nice square.
In the future we will have a "PictureURL" or something like that in this XML for each "categories" item just like the name and value. I could get that working later on my own, I bet, if I can get this working now.
Thank you very much for any help! The XSLT syntax has me still confused after a few days of trying this and googling around.
Here is what I have been trying to make work and could not pull it off:
<table>
<xsl:for-each select="categories[position() mod 5 = 1]">
<xsl:variable name="pos" select="position() - 1" />
<tr>
<td >
<xsl:value-of select="."/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name[position() = ($pos * 5)]"/>
</span>
</td>
<td>
<xsl:value-of select="//categories[position() = ($pos * 5) + 2]"/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name[position() = ($pos * 5) + 2]"/>
</span>
</td>
<td>
<xsl:value-of select="//categories[position() = ($pos * 5) + 3]"/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name[position() = ($pos * 5) + 3]"/>
</span>
</td>
<td>
<xsl:value-of select="//categories[position() = ($pos * 5) + 4]"/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name[position() = ($pos * 5) + 4]"/>
</span>
</td>
<td>
<xsl:value-of select="//categories[position() = ($pos * 5) + 5]"/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name[position() = ($pos * 5) + 5]"/>
</span>
</td>
</tr>
</xsl:for-each>
</table>
This is how I tried to integrate JLRishe's answer into my existing XSLT:
<!--================-->
<!-- Categories -->
<!--================-->
<xsl:template name="WriteCategories">
<xsl:if test="categories">
<div>
<!-- set the class, if browsing it's a larger font -->
<xsl:choose>
<xsl:when test="$pBrowse='True'">
<xsl:attribute name="class">critGroup lg</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class">critGroup</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="numCols" select="5" />
<xsl:template match="/*">
<table>
<xsl:apply-templates select="categories[position() mod $numCols = 1]"
mode="row" />
</table>
</xsl:template>
<xsl:template match="categories" mode="row">
<tr>
<xsl:variable name="thisRowItems"
select=". | following-sibling::categories[position() < $numCols]" />
<xsl:apply-templates select="$thisRowItems" />
<xsl:call-template name="addCells">
<xsl:with-param name="count" select="$numCols - count($thisRowItems)" />
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template match="categories">
<td>
<xsl:value-of select="."/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name" />
</span>
</td>
</xsl:template>
<xsl:template name="addCells">
<xsl:param name="count" />
<xsl:if test="$count > 0">
<td></td>
<xsl:call-template name="addCells">
<xsl:with-param name="count" select="$count - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<div>
<!-- if not browsing, write expandable area if there are more than 5 items -->
<xsl:if test="$pBrowse='False' and count(categories)>5">
<div id="divCritHdnMore_Category" class="moreHidden">
<xsl:for-each select="categories">
<xsl:if test="position()>5">
<div>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name" disable-output-escaping="yes" />
</span>
<xsl:value-of select="concat(' (', count, ')')" />
</div>
</xsl:if>
</xsl:for-each>
</div>
</xsl:if>
</div>
<!-- more link -->
<xsl:if test="$pBrowse='False' and count(categories)>5">
<div class="moreLink">
<span id="spnCritMore_Category" onclick="CriteriaMore('Category')">More . . .</span>
</div>
</xsl:if>
</div>
</xsl:if>
</xsl:template>
This is how you can do table row grouping. I don't think having the right number of <td>s in the last row is strictly necessary, but I've added that capability too:
Add this to your WriteCategories template in the place where you want the table to be:
<table>
<xsl:apply-templates select="categories[position() mod $numCols = 1]"
mode="row" />
</table>
And add this outside of any other templates:
<xsl:variable name="numCols" select="5" />
<xsl:template match="categories" mode="row">
<tr>
<xsl:variable name="thisRowItems"
select=". | following-sibling::categories
[position() < $numCols]" />
<xsl:apply-templates select="$thisRowItems" />
<xsl:call-template name="addCells">
<xsl:with-param name="count" select="$numCols - count($thisRowItems)" />
</xsl:call-template>
</tr>
</xsl:template>
<xsl:template match="categories">
<td>
<xsl:value-of select="."/>
<span onclick="Critia(this, '{value}')">
<xsl:value-of select="name" />
</span>
</td>
</xsl:template>
<xsl:template name="addCells">
<xsl:param name="count" />
<xsl:if test="$count > 0">
<td></td>
<xsl:call-template name="addCells">
<xsl:with-param name="count" select="$count - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
When run on your sample input with the last 3 categories removed to make 12 items, the result is:
<table>
<tr>
<td>
Badges & Holders
1000111
<span onclick="Critia(this, '1000111')">Badges & Holders</span></td>
<td>
Clips, Tacks & Rubber Bands
1000113
<span onclick="Critia(this, '1000113')">Clips, Tacks & Rubber Bands</span></td>
<td>
Clocks
1000114
<span onclick="Critia(this, '1000114')">Clocks</span></td>
<td>
Indexing Flags & Tabs
1000115
<span onclick="Critia(this, '1000115')">Indexing Flags & Tabs</span></td>
<td>
Magnification
1000116
<span onclick="Critia(this, '1000116')">Magnification</span></td>
</tr>
<tr>
<td>
Pad Holders
1000117
<span onclick="Critia(this, '1000117')">Pad Holders</span></td>
<td>
Paper Punch Accessories
1000118
<span onclick="Critia(this, '1000118')">Paper Punch Accessories</span></td>
<td>
Paper Punches
1000119
<span onclick="Critia(this, '1000119')">Paper Punches</span></td>
<td>
Scissors, Rulers & Paper Trimmers
1000120
<span onclick="Critia(this, '1000120')">Scissors, Rulers & Paper Trimmers</span></td>
<td>
Signs & Nameplates
1000121
<span onclick="Critia(this, '1000121')">Signs & Nameplates</span></td>
</tr>
<tr>
<td>
Stamps & Pads Accessories
1000122
<span onclick="Critia(this, '1000122')">Stamps & Pads Accessories</span></td>
<td>
Stapler Accessories
1000123
<span onclick="Critia(this, '1000123')">Stapler Accessories</span></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>