Tuesday, September 14, 2004 8:20 PM, Tham Tinh wrote:
For short example, I would like to display 2 rows
return per page and I will be able to click next or go
back to see next or previouse 2 rows.
Hi Tham,
Your example already groups the WMSReport elements by ReportUnitTitle,
generating a table for each (in your files there's 3 tables: Sail, Training and
Personnel) so suppose there are 11 WMSReport elements with a certain
ReportUnitTitle then you want them to output 6 html files (2 rows each)?
Here's a stylesheet using <xsl:document> to generate multiple output files.
It's version="1.1" because xsl:document is not supported in XSLT 1.0.
- $rows-per-page is provided as stylesheet param, it defaults to "2" but
you can pass another value if you want
- The input file is preprocessed into 2 global variables: $units and $files.
Both variables' result tree fragments (RTF) are automatically converted
to a node-set so you can use select="$files/t:file" instead of
"xx:node-set($files)/t:file". It works in Saxon:
http://saxon.sourceforge.net/saxon6.5.3/conformance.html
- The stylesheet generates an index.html and one html file for every
"$files/t:file" (with 'previous' and 'next' links). Also a styles.css and
a log.xml (dump of the global variables).
- The output files are generated inside a "output" subdirectory,
which you'll have to create before running the transform.
- I added a key "by-id", assuming that your PositionNumber elements
hold a unique ID - if they don't, and if there's no other element with
unique contents to use as an ID, you can use="generate-id()" instead.
- <xsl:for-each select="$root"> is used to set the context to
the source input document, when you want to use a key
to the WMSReport elements (without the for-each, the
key doesn't work if you're in the context of a RTF).
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:t="t-for-temporary" exclude-result-prefixes="t">
<xsl:param name="rows-per-page" select="2"/>
<xsl:param name="encoding" select="'utf-8'"/>
<!-- default output properties, will be inherited by xsl:document -->
<xsl:output method="xml" indent="yes" encoding="{$encoding}"/>
<xsl:key name="by-unit" match="WMSReport" use="ReportUnitTitle"/>
<xsl:key name="by-id" match="WMSReport" use="PositionNumber"/>
<xsl:variable name="root" select="/"/>
<xsl:variable name="records" select="/dsWMSRpt/WMSReport"/>
<xsl:variable name="units">
<!-- collection of t:unit elements, one for every ReportUnitTitle -->
<xsl:apply-templates select="$records[generate-id(.) =
generate-id(key('by-unit', ReportUnitTitle))]" mode="units">
<xsl:sort select="ApptStatusCode" order="ascending"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:template match="WMSReport" mode="units" xmlns="">
<t:unit name="{ReportUnitTitle}">
<xsl:apply-templates select="key('by-unit', ReportUnitTitle)" mode="row">
<xsl:sort select="Person_x0020_Name" order="ascending"/>
</xsl:apply-templates>
</t:unit>
</xsl:template>
<xsl:template match="WMSReport" mode="row" xmlns="">
<!-- add one t:row for every table row, store position in @pos (current sort
order) -->
<t:row id="{PositionNumber}" pos="{position()}"/>
</xsl:template>
<xsl:variable name="files">
<!-- collection of t:file elements, one for every output file -->
<xsl:apply-templates select="$units/t:unit/t:row[number(@pos) mod
$rows-per-page = 1]" mode="files"/>
</xsl:variable>
<xsl:template match="t:row" mode="files" xmlns="">
<xsl:variable name="unit" select="parent::t:unit/@name"/>
<xsl:variable name="nr" select="ceiling(count(preceding-sibling::t:row) div
$rows-per-page + 1)"/>
<xsl:variable name="name" select="concat($unit, '-', $nr)"/>
<t:file unit="{$unit}" name="{$name}">
<!-- copy the correct number of t:row elements from $units -->
<xsl:copy-of select=".|following-sibling::t:row[position() <
$rows-per-page]"/>
</t:file>
</xsl:template>
<xsl:template match="/">
<!-- input root node: start generating output files -->
<xsl:call-template name="log"/>
<xsl:call-template name="styles"/>
<xsl:call-template name="index"/>
<xsl:apply-templates select="$files/t:file" mode="page"/>
</xsl:template>
<xsl:template name="log" xmlns="">
<!-- generate log.xml (dump global variables) -->
<xsl:document href="output/log.xml">
<t:log rows-per-page="{$rows-per-page}" record-count="{count($records)}">
<t:units count="{count($units/*)}">
<xsl:copy-of select="$units"/>
</t:units>
<t:files count="{count($files/*)}">
<xsl:copy-of select="$files"/>
</t:files>
</t:log>
</xsl:document>
</xsl:template>
<xsl:template name="styles">
<!-- generate styles.css -->
<xsl:document href="output/styles.css" method="text">
body { background: #ddd; }
h1, h2, h3 { text-align: center; }
a:hover { background: #6ee; }
table { width: 100%; }
th { font-size: 75%; }
tr.odd td { background: #fff; }
tr.evn td { background: #bbb; }
#nav { padding-top: 2em; text-align: center; }
#nav tr td { width: 33%; }
</xsl:document>
</xsl:template>
<xsl:template name="index">
<!-- generate index.html -->
<xsl:document href="output/index.html"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<xsl:call-template name="html-head">
<xsl:with-param name="title" select="'index'"/>
</xsl:call-template>
<body>
<h1>index</h1>
<ul>
<xsl:apply-templates select="$units/t:unit" mode="index"/>
</ul>
</body>
</html>
</xsl:document>
</xsl:template>
<xsl:template match="t:unit" mode="index">
<li>
<a href="{(_at_)name}-1(_dot_)html"><xsl:value-of select="@name"/></a>
<xsl:text/> (<xsl:value-of select="count(t:row)"/> records)<xsl:text/>
</li>
</xsl:template>
<xsl:template name="html-head">
<xsl:param name="title" select="''"/>
<head>
<title><xsl:value-of select="$title"/></title>
<meta http-equiv="content-type" content="text/html;charset={$encoding}"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
</head>
</xsl:template>
<xsl:template match="t:file" mode="page">
<!-- generate html file for every t:file -->
<xsl:document href="output/{(_at_)name}(_dot_)html"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<xsl:call-template name="html-head">
<xsl:with-param name="title" select="@name"/>
</xsl:call-template>
<body>
<xsl:variable name="unit" select="@unit"/>
<xsl:for-each select="$root">
<xsl:apply-templates select="key('by-unit', $unit)[1]" mode="page"/>
</xsl:for-each>
<table border="1">
<xsl:call-template name="table-header"/>
<xsl:apply-templates select="t:row" mode="table-row"/>
</table>
<xsl:call-template name="nav"/>
</body>
</html>
</xsl:document>
</xsl:template>
<xsl:template match="WMSReport" mode="page">
<h2><xsl:value-of select="Administration"/></h2>
<h3><xsl:value-of select="ReportUnitTitle"/></h3>
</xsl:template>
<xsl:template name="table-header">
<tr>
<th>WMS Working Title</th>
<th>Position Number</th>
<th>Person Name</th>
<th>Annual Salary</th>
<th>Job Cls</th>
<th>Band</th>
<th>JVA Code</th>
<th>Salary Standard</th>
<th>Peer Group</th>
<th>Employee Status</th>
<th>Occ CD</th>
</tr>
</xsl:template>
<xsl:template match="t:row" mode="table-row">
<xsl:variable name="id" select="@id"/>
<xsl:variable name="pos" select="position()"/>
<xsl:for-each select="$root">
<xsl:apply-templates select="key('by-id', $id)" mode="table-row">
<xsl:with-param name="pos" select="$pos"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="WMSReport" mode="table-row">
<xsl:param name="pos"/>
<xsl:variable name="class">
<xsl:choose>
<xsl:when test="($pos mod 2 = 1)">odd</xsl:when>
<xsl:otherwise>evn</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<tr class="{$class}">
<td><xsl:value-of select="WMS_x0020_Working_x0020_Title"/></td>
<td><xsl:value-of select="PositionNumber"/></td>
<td><xsl:value-of select="Person_x0020_Name"/></td>
<td><xsl:apply-templates select="AnnualSalary" mode="format-salary"/></td>
<td><xsl:value-of select="JobClassCode"/></td>
<td><xsl:value-of select="Band"/></td>
<td><xsl:value-of select="JVACode"/></td>
<td><xsl:apply-templates select="Salary_x0020_Standard"
mode="format-salary"/></td>
<td><xsl:value-of select="Peer_x0020_Group"/></td>
<td><xsl:value-of select="concat(ApptStatusCode, ' ',
AppointmentStatusTitle)"/></td>
<td><xsl:value-of select="OccupationCode"/></td>
</tr>
</xsl:template>
<xsl:template match="*" mode="format-salary">
<xsl:choose>
<xsl:when test="number(.) > 0">
<xsl:value-of select="format-number(., '$###,###.00')"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="nav">
<!-- add "previous" and "next" links -->
<table id="nav" border="0">
<tr>
<td><a href="index.html">index</a></td>
<td><xsl:apply-templates select="preceding-sibling::t:file[1]"
mode="prev"/></td>
<td><xsl:apply-templates select="following-sibling::t:file[1]"
mode="next"/></td>
</tr>
</table>
</xsl:template>
<xsl:template match="t:file" mode="prev">
<a href="{(_at_)name}(_dot_)html">previous</a>
</xsl:template>
<xsl:template match="t:file" mode="next">
<a href="{(_at_)name}(_dot_)html">next</a>
</xsl:template>
</xsl:stylesheet>
If you have any questions don't hesitate to ask!
Cheers,
Anton
This may be hairy codes, but please help me.
XSLT code:
<?xml version='1.0' encoding='utf-8' ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<!--
Step 1: Define the primary key to be used in the
Muenchian grouping. The
beautiful thing about the xsl:key element in our
example is that once we
know the "Administration", we can easily find all of
the WMSReport that match that Administration.
The xsl:key element (different from the key()
function) is defined as follows:-->
<xsl:key name="dsWMSRpt" match="WMSReport"
use="ReportUnitTitle"/>
<!-- Template for our root rule -->
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- Template for our "dsWMSRpt" rule -->
<xsl:template match="dsWMSRpt">
<!--Step 2: Loop through the unique regions (the
primary key) in our document. -->
<xsl:for-each
select="//WMSReport[generate-id(.)=generate-id(key('dsWMSRpt',ReportUnitTitle))]">
<!-- Sort Primary key by ApptStatusCode in
ascending order -->
<xsl:sort select="ApptStatusCode"
order="ascending"/>
<!-- Display the region as our table header -->
<h2 align="Center"><xsl:value-of
select="Administration"/></h2>
<h3 align="Center"><xsl:value-of
select="ReportUnitTitle"/></h3>
<!--Display all nodes for a given Administration
in a table-->
<table border="0">
<tr>
<th>WMS Working Title</th>
<th>Position Number</th>
<th>Person Name</th>
<th>Annual Salary</th>
<th>Job Cls</th>
<th>Band</th>
<th>JVA Code</th>
<th>Salary Standard</th>
<th>Peer Group</th>
<th>Employee Status</th>
<th>Occ CD</th>
</tr>
<!-- For each value in our key collection for the
given Administration display values -->
<xsl:for-each
select="key('dsWMSRpt',ReportUnitTitle)">
<!--
The expression "key('dsWMSRpt',Administration)"
will return all of the "WMSReport"
elements from the key table whose "use="
expression defined in xsl:key
(see xsl:key at top) evaluated to the same value
as the "Administration" child
of the current element. In the the example, we
specified use="Admnistration".
If Administration has a value of ".EXEC", then
all of the WMSReport elements from
the key table that contain a child element with a
value of ".EXEC" will
be returned.
-->
<!--Sort our secondary key, product nodes, by
ApptStatusCode-->
<xsl:sort select="ApptStatusCode"/>
<tr>
<xsl:if test="(position() mod 2 = 1)">
<xsl:attribute
name="bgcolor">#ccffff</xsl:attribute>
</xsl:if>
<td><xsl:value-of
select="WMS_x0020_Working_x0020_Title"/></td>
<td><xsl:value-of
select="PositionNumber"/></td>
<td><xsl:value-of
select="Person_x0020_Name"/></td>
<td>
<xsl:choose>
<xsl:when test="AnnualSalary>0">
<!--format number function has been used
in the next line-->
<xsl:value-of
select='format-number(AnnualSalary, "$###,###.00")' />
</xsl:when>
<xsl:otherwise>
0
</xsl:otherwise>
</xsl:choose>
</td>
<td><xsl:value-of
select="JobClassCode"/></td>
<td><xsl:value-of select="Band"/></td>
<td><xsl:value-of select="JVACode"/></td>
<td>
<xsl:choose>
<xsl:when
test="Salary_x0020_Standard>0">
<!--format number function has been used
in the next line-->
<xsl:value-of
select='format-number(Salary_x0020_Standard,
"$###,###.00")' />
</xsl:when>
<xsl:otherwise>
0
</xsl:otherwise>
</xsl:choose>
</td>
<td><xsl:value-of
select="Peer_x0020_Group"/></td>
<!--concat function has been used in the next
line-->
<td><xsl:value-of
select='concat(ApptStatusCode, " ",
AppointmentStatusTitle)' /></td>
<td><xsl:value-of
select="OccupationCode"/></td>
<!--/xsl:when-->
<!--/xsl:choose-->
</tr>
</xsl:for-each>
</table>
<br>
Employee Count: <xsl:value-of
select="count(key('dsWMSRpt',ReportUnitTitle)[Person_x0020_Name!='Vacancy'
and Person_x0020_Name!=''])"/>
</br>
<br>
Vacant Position Count: <xsl:value-of
select="count(key('dsWMSRpt',ReportUnitTitle)[Person_x0020_Name='Vacancy'])"/>
</br>
<br>
Total Position Count: <xsl:value-of
select="count(key('dsWMSRpt',ReportUnitTitle))"/>
</br>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XML data:
<?xml version="1.0" standalone="yes"?>
<dsWMSRpt>
<WMSReport>
<AdministrationCode>HRS</AdministrationCode>
<DivisionSort>HRS/Finacial</DivisionSort>
<Status_x0020_Order>1</Status_x0020_Order>
<Administration>Finacial</Administration>
<DivisionTitle>Sale</DivisionTitle>
<ReportUnitTitle>Sail</ReportUnitTitle>
<WMS_x0020_Working_x0020_Title>Sale
Rep.</WMS_x0020_Working_x0020_Title>
<PositionNumber> JP17</PositionNumber>
<Person_x0020_Name>Green, Cloud
</Person_x0020_Name>
<ApptSalaryUnitCode>M</ApptSalaryUnitCode>
<SalaryUnitAmount>6050.0000</SalaryUnitAmount>
<AnnualSalary>72600</AnnualSalary>
<Band>1</Band>
<JVACode>000</JVACode>
<Salary_x0020_Standard>74760.0000</Salary_x0020_Standard>
<Peer_x0020_Group>Q</Peer_x0020_Group>
<ApptStatusCode>0</ApptStatusCode>
<AppointmentStatusTitle>Temporary</AppointmentStatusTitle>
<ApptJobClassCode>SR</ApptJobClassCode>
<JobClassCode>SR</JobClassCode>
<ApptPartTimePct>100</ApptPartTimePct>
<PositionCountyCode>27</PositionCountyCode>
<PersonID>111111111</PersonID>
<PositionOrgCode>000</PositionOrgCode>
<SeniorityDate>2003-11-20T00:00:00.0000000-08:00</SeniorityDate>
<OccupationCode>183</OccupationCode>
<SnapshotDate>2004-08-08T00:00:00.0000000-07:00</SnapshotDate>
<ReportingUnitID>38</ReportingUnitID>
<SupervisorInd>Y</SupervisorInd>
</WMSReport>
<WMSReport>
<AdministrationCode>HRS</AdministrationCode>
<DivisionSort>HRS/Finacial</DivisionSort>
<Status_x0020_Order>1</Status_x0020_Order>
<Administration>Finacial</Administration>
<DivisionTitle>Sale</DivisionTitle>
<ReportUnitTitle>Sail</ReportUnitTitle>
<WMS_x0020_Working_x0020_Title>Sale
Rep.</WMS_x0020_Working_x0020_Title>
<PositionNumber> SDSS</PositionNumber>
<Person_x0020_Name>Shine, Sun </Person_x0020_Name>
<ApptSalaryUnitCode>M</ApptSalaryUnitCode>
<SalaryUnitAmount>6050.0000</SalaryUnitAmount>
<AnnualSalary>72600</AnnualSalary>
<Band>1</Band>
<JVACode>000</JVACode>
<Salary_x0020_Standard>74760.0000</Salary_x0020_Standard>
<Peer_x0020_Group>Q</Peer_x0020_Group>
<ApptStatusCode>0</ApptStatusCode>
<AppointmentStatusTitle>Temporary</AppointmentStatusTitle>
<ApptJobClassCode>SR</ApptJobClassCode>
<JobClassCode>SR</JobClassCode>
<ApptPartTimePct>100</ApptPartTimePct>
<PositionCountyCode>27</PositionCountyCode>
<PersonID>44444444444</PersonID>
<PositionOrgCode>000</PositionOrgCode>
<SeniorityDate>2003-11-20T00:00:00.0000000-08:00</SeniorityDate>
<OccupationCode>183</OccupationCode>
<SnapshotDate>2004-08-08T00:00:00.0000000-07:00</SnapshotDate>
<ReportingUnitID>38</ReportingUnitID>
<SupervisorInd>Y</SupervisorInd>
</WMSReport>
<WMSReport>
<AdministrationCode>HRS</AdministrationCode>
<DivisionSort>HRS/Personnel</DivisionSort>
<Status_x0020_Order>Z</Status_x0020_Order>
<Administration>Personnel</Administration>
<DivisionTitle>Some Thing</DivisionTitle>
<ReportUnitTitle>Personnel</ReportUnitTitle>
<WMS_x0020_Working_x0020_Title>IT</WMS_x0020_Working_x0020_Title>
<PositionNumber>SDFG</PositionNumber>
<Person_x0020_Name>Red, Brow</Person_x0020_Name>
<ApptSalaryUnitCode>M</ApptSalaryUnitCode>
<SalaryUnitAmount>2984.0000</SalaryUnitAmount>
<AnnualSalary>35808</AnnualSalary>
<Band>1</Band>
<JVACode>456</JVACode>
<Salary_x0020_Standard>53112.0000</Salary_x0020_Standard>
<Peer_x0020_Group>B</Peer_x0020_Group>
<ApptStatusCode>K</ApptStatusCode>
<AppointmentStatusTitle>Manager-ACTING</AppointmentStatusTitle>
<ApptJobClassCode>WMS</ApptJobClassCode>
<JobClassCode>WMS</JobClassCode>
<ApptPartTimePct>100</ApptPartTimePct>
<PositionCountyCode>34</PositionCountyCode>
<PersonID>222222222</PersonID>
<PositionOrgCode>G70 </PositionOrgCode>
<SeniorityDate>2003-10-01T00:00:00.0000000-07:00</SeniorityDate>
<OccupationCode>180</OccupationCode>
<SnapshotDate>2004-08-08T00:00:00.0000000-07:00</SnapshotDate>
<ReportingUnitID>34</ReportingUnitID>
<SupervisorInd>Y</SupervisorInd>
</WMSReport>
<WMSReport>
<AdministrationCode>HRS</AdministrationCode>
<DivisionSort>HRS/Traninig</DivisionSort>
<Status_x0020_Order>1</Status_x0020_Order>
<Administration>Personnel</Administration>
<DivisionTitle>Training</DivisionTitle>
<ReportUnitTitle>Training</ReportUnitTitle>
<WMS_x0020_Working_x0020_Title>Training
Specialist</WMS_x0020_Working_x0020_Title>
<PositionNumber>DREW</PositionNumber>
<Person_x0020_Name>White, Golden
</Person_x0020_Name>
<ApptSalaryUnitCode>M</ApptSalaryUnitCode>
<SalaryUnitAmount>5043.0000</SalaryUnitAmount>
<AnnualSalary>60516</AnnualSalary>
<Band>2</Band>
<JVACode>456</JVACode>
<Salary_x0020_Standard>60516.0000</Salary_x0020_Standard>
<Peer_x0020_Group>C1</Peer_x0020_Group>
<ApptStatusCode>3</ApptStatusCode>
<AppointmentStatusTitle>TRIAL
SERVICE</AppointmentStatusTitle>
<ApptJobClassCode>WMS</ApptJobClassCode>
<JobClassCode>WMS</JobClassCode>
<ApptPartTimePct>100</ApptPartTimePct>
<PositionCountyCode>34</PositionCountyCode>
<PersonID>333333333</PersonID>
<PositionOrgCode>DSF</PositionOrgCode>
<SeniorityDate>2004-01-02T00:00:00.0000000-08:00</SeniorityDate>
<OccupationCode>600</OccupationCode>
<SnapshotDate>2004-08-08T00:00:00.0000000-07:00</SnapshotDate>
<ReportingUnitID>19</ReportingUnitID>
<SupervisorInd>N</SupervisorInd>
</WMSReport>
<WMSReport>
<AdministrationCode>HRS</AdministrationCode>
<DivisionSort>HRS/Traninig</DivisionSort>
<Status_x0020_Order>1</Status_x0020_Order>
<Administration>Personnel</Administration>
<DivisionTitle>Training</DivisionTitle>
<ReportUnitTitle>Training</ReportUnitTitle>
<WMS_x0020_Working_x0020_Title>Training
Specialist</WMS_x0020_Working_x0020_Title>
<PositionNumber>EWQS</PositionNumber>
<Person_x0020_Name>Gate, Golden
</Person_x0020_Name>
<ApptSalaryUnitCode>M</ApptSalaryUnitCode>
<SalaryUnitAmount>5043.0000</SalaryUnitAmount>
<AnnualSalary>60516</AnnualSalary>
<Band>2</Band>
<JVACode>456</JVACode>
<Salary_x0020_Standard>60516.0000</Salary_x0020_Standard>
<Peer_x0020_Group>C1</Peer_x0020_Group>
<ApptStatusCode>3</ApptStatusCode>
<AppointmentStatusTitle>TRIAL
SERVICE</AppointmentStatusTitle>
<ApptJobClassCode>WMS</ApptJobClassCode>
<JobClassCode>WMS</JobClassCode>
<ApptPartTimePct>100</ApptPartTimePct>
<PositionCountyCode>34</PositionCountyCode>
<PersonID>333333333</PersonID>
<PositionOrgCode>FET</PositionOrgCode>
<SeniorityDate>2004-01-02T00:00:00.0000000-08:00</SeniorityDate>
<OccupationCode>600</OccupationCode>
<SnapshotDate>2004-08-08T00:00:00.0000000-07:00</SnapshotDate>
<ReportingUnitID>19</ReportingUnitID>
<SupervisorInd>N</SupervisorInd>
</WMSReport>
</dsWMSRpt>
=====
"It is essential to know that to be a happy person, a happy family, a happy
society, it is very crucial to have a good heart, that
is very crucial,"
Dalai Lama