Reputation: 197
i'm trying to use a for-each statement to create a table for each element "bill". The XML document is the following:
<group>
<name>Casa Miles</name>
<student>
<id>sergio</id>
<name>sergio</name>
<surname>zavota</surname>
<bill>
<product>
<name>sapone piatti</name>
<amount>1</amount>
<prize>3.3</prize>
<participant>
<id>stefano</id>
</participant>
</product>
<product>
<name>bresaola</name>
<amount>1</amount>
<prize>5.5</prize>
<participant>
<id>sergio</id>
</participant>
</product>
<date>2020-02-03</date>
</bill>
</student>
<student>
<id>stefano</id>
<name>stefano</name>
<surname>silvestri</surname>
<bill>
<product>
<name>liquore</name>
<amount>2</amount>
<prize>5.00</prize>
<participant>
<id>stefano</id>
</participant>
</product>
<product>
<name>coniglio</name>
<amount>1</amount>
<prize>4.5</prize>
<participant>
<id>stefano</id>
</participant>
</product>
<date>2020-03-03</date>
</bill>
</student>
</group>
I tried to use Muenchian grouping, but instead of getting two table (one for each date/bill), i get just one table with the date of the first bill (from top to down of the XML document) and two rows, one for each of the first product of each bill, as shown in this image.
The XSLT doc is the following:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="tableByBillDate" match="bill" use="date" />
<xsl:template match="/">
<html>
<head>
<title>HTML Document</title>
</head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
caption {
display: table-caption;
text-align: center;
}
</style>
<body>
<h3>Welcome<xsl:value-of select="group/student/name"/></h3>
<h3>Group: <xsl:value-of select="group/name"/> </h3>
<h3>Bills</h3>
<xsl:for-each select="group/student/bill[generate-id() = generate
id(key('tableByBillDate',date)[1])]">
<table>
<caption style="font-weight: bold;">Date: <xsl:value-of select="date"/></caption>
<tr>
<th>Name</th>
<th>Amount</th>
<th>Cost</th>
<th>Total</th>
<th>Participants</th>
</tr>
<xsl:for-each select="key('tableByBillDate',date)">
<xsl:sort select="date" order="descending"/>
<tr>
<td><xsl:value-of select="product/name"/></td>
<td><xsl:value-of select="product/amount"/></td>
<td><xsl:value-of select="product/prize"/></td>
<td>Calculated with Javascript</td>
<td><xsl:value-of select="product/participant"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 485
Reputation: 34
Please find the correct following:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="yes"/>
<xsl:key name="tableByBillDate" match="bill" use="date" />
<xsl:template match="/">
<html>
<head>
<title>HTML Document</title>
</head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
caption {
display: table-caption;
text-align: center;
}
</style>
<body>
<h3 align="center">Welcome: <xsl:value-of select="group/student/name"/></h3>
<h3 align="center">Group: <xsl:value-of select="group/name"/> </h3>
<h3 align="center">Bills</h3>
<xsl:for-each select="group/student/bill[generate-id()= generate-id(key('tableByBillDate',date)[1])]">
<table>
<caption style="font-weight: bold;">Date: <xsl:value-of select="date"/></caption>
<tr>
<th>Name</th>
<th>Amount</th>
<th>Cost</th>
<th>Total</th>
<th>Participants</th>
</tr>
<xsl:for-each select="key('tableByBillDate',date)">
<xsl:sort select="date" order="descending"/>
<tr>
<td><xsl:value-of select="product/name"/></td>
<td><xsl:value-of select="product/amount"/></td>
<td><xsl:value-of select="product/prize"/></td>
<td>Calculated with Javascript</td>
<td><xsl:value-of select="product/participant"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/gVhDDyA/5
Upvotes: 2
Reputation: 167696
I also think your used key should give you two tables with the sample data you have show, as you have two different dates; if you want to output all product data in each table then process all product
s in a "group":
<?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" indent="yes" version="5" doctype-system="about:legacy-doctype"/>
<xsl:key name="tableByBillDate" match="bill" use="date" />
<xsl:template match="group">
<xsl:apply-templates select="student/bill[generate-id() = generate-id(key('tableByBillDate', date)[1])]">
<xsl:sort select="date"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="bill">
<table>
<caption style="font-weight: bold;">Date: <xsl:value-of select="date"/></caption>
<thead>
<tr>
<th>Name</th>
<th>Amount</th>
<th>Cost</th>
<th>Total</th>
<th>Participants</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="key('tableByBillDate',date)/product"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="product">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="amount"/></td>
<td><xsl:value-of select="prize"/></td>
<td>Calculated with Javascript</td>
<td><xsl:value-of select="participant"/></td>
</tr>
</xsl:template>
<xsl:template match="/">
<html>
<head>
<title>.NET XSLT Fiddle Example</title>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
caption {
display: table-caption;
text-align: center;
}
</style>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/3MvmXis
Upvotes: 2