XML Generate Columns by Group using XSLT
I am trying to generate a 4 column directory, grouped by the 4 disciplines in my department. One XML file contains the entire group. Each element has a department tag. The construction of the directory would be the following:
Group each entry by discipline.
For each group, cycle through each entry. If the Rank equals Supervisor, fill out the supervisor DIV, otherwise keep generating a div for each person in the group. Once all entries in the group are exhausted, construct the next column for the next group... Keep going until all groups are exhausted.I'm new to XSLT and really need help. I can create a key for each group, and cycle through the entries in the group, but I'm not sure how to cycle through the different groups.
My mark up is below.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="group" match="employee" use="dept" />
<xsl:template match="/">
<div id="directory">
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
<xsl:for-each select="key('group', 'Mechanical')">
<xsl:sort select="name" order="ascending"/>
(I need a conditional here to check if rank = supervisor)
<div class="super">
<h1>Supervisor</h1>
<h2><xsl:value-of select="name"/></h2>
</div>
<div>
<p class="name"><xsl:value-of select="name"/></p>
<p class="ID"><xsl:value-of select="id"/></p>
</div>
</xsl:for-each>
</div>
XML Directory
<?xml version="1.0" encoding="ISO-8859-1" ?>
<directory>
<employee>
<dept></dept>
<rank>Manager</rank>
<name>John Doe</name>
<id>1234</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
</directory>
Output would look something like:
HTML should look something like:
<div id="directory">
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
<div class="super">
<h1>Mechanical Supervisor</h1>
<h2>Supervisor Name</h2>
</div>
<div>
<p class="name">Mech employee name</p>
<p class="ID">Mech employee ID</p>
</div><!--end group A-->
<div class="group">
<div class="super">
<h1>CivilSupervisor</h1>
<h2>Supervisor Name</h2>
</div>
<div>
<p class="name">Civil employee name</p>
<p class="ID">Civil employee ID</p>
</div><!--end group B-->
<div class="group">
<div class="super">
<h1>Electrical Supervisor</h1>
<h2>Supervisor Name</h2&g开发者_高级运维t;
</div>
<div>
<p class="name">Electrical employee name</p>
<p class="ID">Electrical employee ID</p>
</div><!--end group C-->
</div>
This XSLT 1.0 transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kEmpByDeptRank" match="employee"
use="concat(dept,'+', rank)"/>
<xsl:key name="kEmpByDept" match="employee"
use="dept"/>
<xsl:template match="directory">
<div id="directory">
<xsl:apply-templates select=
"key('kEmpByDeptRank', '+Manager')"/>
<xsl:apply-templates select=
"employee[not(rank='Manager')]"/>
</div>
</xsl:template>
<xsl:template match=
"employee[generate-id()
=
generate-id(key('kEmpByDept', dept)[1])
]
">
<div class="group">
<xsl:apply-templates mode="inGroup" select=
"key('kEmpByDeptRank', concat(dept,'+Supervisor'))"/>
<xsl:apply-templates mode="inGroup" select=
"key('kEmpByDept', dept)[not(rank='Supervisor')]"/>
</div>
</xsl:template>
<xsl:template match="employee[rank='Manager']">
<div class="man">
<h1>Manager</h1>
<h2><xsl:value-of select="name"/></h2>
</div>
</xsl:template>
<xsl:template match="employee[rank='Supervisor']"
mode="inGroup">
<div class="super">
<h1>
<xsl:value-of select="concat(dept, ' Supervisor')"/>
</h1>
<h2><xsl:value-of select="name"/></h2>
</div>
</xsl:template>
<xsl:template match="employee" mode="inGroup">
<div>
<p class="name">
<xsl:value-of select="concat(dept, ' ', name)"/>
</p>
<p class="ID">
<xsl:value-of select="concat(dept, ' ', id)"/>
</p>
</div>
</xsl:template>
<xsl:template match="employee"/>
</xsl:stylesheet>
when applied on this XML document (similar to the provided one, but changed the names and Ids to be distinct):
<directory>
<employee>
<dept></dept>
<rank>Manager</rank>
<name>John Doe</name>
<id>1234</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>Supervisor</rank>
<name>Jane Doe</name>
<id>4321</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Joe Doe</name>
<id>2314</id>
</employee>
<employee>
<dept>Mechanical</dept>
<rank>General</rank>
<name>Jim Smith</name>
<id>2315</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>Supervisor</rank>
<name>Ann Smith</name>
<id>4322</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Peter Pan</name>
<id>2316</id>
</employee>
<employee>
<dept>Civil</dept>
<rank>General</rank>
<name>Mike Sims</name>
<id>2317</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>Supervisor</rank>
<name>Amy Dull</name>
<id>4323</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>Dan Brown</name>
<id>2318</id>
</employee>
<employee>
<dept>Electrical</dept>
<rank>General</rank>
<name>John Kerry</name>
<id>2319</id>
</employee>
</directory>
produces the wanted, correct result:
<div id="directory">
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
<div class="super">
<h1>Mechanical Supervisor</h1>
<h2>Jane Doe</h2>
</div>
<div>
<p class="name">Mechanical Joe Doe</p>
<p class="ID">Mechanical 2314</p>
</div>
<div>
<p class="name">Mechanical Jim Smith</p>
<p class="ID">Mechanical 2315</p>
</div>
</div>
<div class="group">
<div class="super">
<h1>Civil Supervisor</h1>
<h2>Ann Smith</h2>
</div>
<div>
<p class="name">Civil Peter Pan</p>
<p class="ID">Civil 2316</p>
</div>
<div>
<p class="name">Civil Mike Sims</p>
<p class="ID">Civil 2317</p>
</div>
</div>
<div class="group">
<div class="super">
<h1>Electrical Supervisor</h1>
<h2>Amy Dull</h2>
</div>
<div>
<p class="name">Electrical Dan Brown</p>
<p class="ID">Electrical 2318</p>
</div>
<div>
<p class="name">Electrical John Kerry</p>
<p class="ID">Electrical 2319</p>
</div>
</div>
</div>
and it displays in the browser as:
Manager
John Doe
Mechanical Supervisor
Jane Doe
Mechanical Joe Doe Mechanical 2314 Mechanical Jim Smith Mechanical 2315Civil Supervisor
Ann Smith
Civil Peter Pan Civil 2316 Civil Mike Sims Civil 2317Electrical Supervisor
Amy Dull
Electrical Dan Brown Electrical 2318 Electrical John Kerry Electrical 2319Explanation: Muenchian method for grouping, and locating an employee
(Manager or Supervisor) using a composite key (rank, department)
.
精彩评论