Reputation: 21
I have xml data from the database. These are the events happening on certain days of the week. There may be a single or multiple events on a particular day.
I need to display events information in a table arranged by the day. Like Monday as heading then a table with event information Then Tuesday as heading and then 2 entries in Tuesday's table.
I realised I may need grouping based on the Weekday. I have not much experience of xslt. How do we go about it? Browsers do not support xslt 2.0 so I have to use xsl 1.0 . I have to parse the xml and display it as html.
<Events>
<Event>
<ActivityTypeName>Lab</ActivityTypeName>
<WeekDay>Wednesday</WeekDay>
<LocalDate>01/04/20</LocalDate>
<Location>Eng. G29 Wet Lab</Location>
</Event>
<Event>
<ActivityName>MAT427-MTRM061-DEN7601-DENM601-DENM600-DEN7600/B/Lec/02 [jt]</ActivityName>
<ActivityTypeName>Lecture</ActivityTypeName>
<WeekDay>Wednesday</WeekDay>
<LocalDate>02/04/20</LocalDate>
<Location>Eng:2.16(42)</Location>
</Event>
<Event>
<ActivityTypeName>Lecture</ActivityTypeName>
<WeekDay>Thursday</WeekDay>
<LocalDate>02/04/20</LocalDate>
<Location>Eng:2.16(42)</Location>
</Event>
<Event>
<ActivityTypeName>Seminar</ActivityTypeName>
<WeekDay>Friday</WeekDay>
<LocalDate>03/04/20</LocalDate>
<Location>Graduate Ctr: GC102 (19)</Location>
</Event>
Upvotes: 0
Views: 160
Reputation: 1369
Let's concentrate on the xsl stylesheet, irrespective of where and how you apply it.
Presuming that your events are streamed in weekday and date order, I would create a key over the first event of succeeding events on a weekday. This approach allows us to easily iterate over those 'first' events and create independent tables.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<!-- index first of sequentially occurring Event elements by WeekDay -->
<xsl:key name="firstof_weekday_key" match="/Events/Event[(position() = 1) or (WeekDay != preceding-sibling::Event[1]/WeekDay)]" use="WeekDay"/>
<xsl:template match="/Events">
<html>
<head>
<style type="text/css">
.Table
{
display: table;
}
.Caption
{
display: table-caption;
text-align: center;
font-weight: bold;
font-size: larger;
}
.THead
{
display: table-header-group;
}
.TBody
{
display: table-row-group;
}
.Heading
{
display: table-row;
font-weight: bold;
text-align: center;
}
.Row
{
display: table-row;
}
.Cell
{
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
</style>
</head>
<body>
<!-- select first Event of WeekDay (which is included in the key) -->
<xsl:apply-templates select="Event[count(. | key('firstof_weekday_key', WeekDay)) = count(key('firstof_weekday_key', WeekDay))]" mode="first"/>
</body>
</html>
</xsl:template>
<xsl:template match="/Events/Event" mode="first">
<div class="Table">
<div class="Caption">
<xsl:value-of select="WeekDay"/>
</div>
<div class="THead">
<div class="Heading">
<div class="Cell">
<xsl:value-of select="'Activity'"/>
</div>
<div class="Cell">
<xsl:value-of select="'Location'"/>
</div>
<div class="Cell">
<xsl:value-of select="'Date'"/>
</div>
</div>
</div>
<div class="TBody">
<xsl:apply-templates select="." mode="data"/>
</div>
</div>
</xsl:template>
<xsl:template match="/Events/Event" mode="data">
<div class="Row">
<div class="Cell">
<xsl:value-of select="ActivityTypeName"/>
</div>
<div class="Cell">
<xsl:value-of select="Location"/>
</div>
<div class="Cell">
<xsl:value-of select="LocalDate"/>
</div>
</div>
<!-- get the next Event in the current WeekDay group -->
<xsl:apply-templates select="following-sibling::Event[1][WeekDay = current()/WeekDay]" mode="data"/>
</xsl:template>
</xsl:stylesheet>
This xslt will transform your events into the following html:
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.Table
{
display: table;
}
.Caption
{
display: table-caption;
text-align: center;
font-weight: bold;
font-size: larger;
}
.THead
{
display: table-header-group;
}
.TBody
{
display: table-row-group;
}
.Heading
{
display: table-row;
font-weight: bold;
text-align: center;
}
.Row
{
display: table-row;
}
.Cell
{
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
</style>
</head>
<body>
<div class="Table">
<div class="Caption">Wednesday</div>
<div class="THead">
<div class="Heading">
<div class="Cell">Activity</div>
<div class="Cell">Location</div>
<div class="Cell">Date</div>
</div>
</div>
<div class="TBody">
<div class="Row">
<div class="Cell">Lab</div>
<div class="Cell">Eng. G29 Wet Lab</div>
<div class="Cell">01/04/20</div>
</div>
<div class="Row">
<div class="Cell">Lecture</div>
<div class="Cell">Eng:2.16(42)</div>
<div class="Cell">02/04/20</div>
</div>
</div>
</div>
<div class="Table">
<div class="Caption">Thursday</div>
<div class="THead">
<div class="Heading">
<div class="Cell">Activity</div>
<div class="Cell">Location</div>
<div class="Cell">Date</div>
</div>
</div>
<div class="TBody">
<div class="Row">
<div class="Cell">Lecture</div>
<div class="Cell">Eng:2.16(42)</div>
<div class="Cell">02/04/20</div>
</div>
</div>
</div>
<div class="Table">
<div class="Caption">Friday</div>
<div class="THead">
<div class="Heading">
<div class="Cell">Activity</div>
<div class="Cell">Location</div>
<div class="Cell">Date</div>
</div>
</div>
<div class="TBody">
<div class="Row">
<div class="Cell">Seminar</div>
<div class="Cell">Graduate Ctr: GC102 (19)</div>
<div class="Cell">03/04/20</div>
</div>
</div>
</div>
</body>
</html>
Upvotes: 1