XML : XSL to transform XML to HTML, filter elements from multiple structures for the same element value

I am a newcomer to XML/XSLT and, so far, in searching SO and the W3SChools sites for clever stuff on Meunchian grouping I haven't been able to grasp an effective solution to my challenge.

Essentially I have one large XML file exported from a database (which means I can't directly edit the XML) which contains invoicing information.

I want to utilise XSLT (1.0) to apply a transformation of the XML into HTML (I am using Saxon) so that each invoice is displayed as a table. However, in the XML, there are many product lines which relate to the same invoice (denoted by the <invoiceNum> element as the identifier).

I don't want to have to create & display a new table for each product line which is part of the same invoice. In my current XSL file, I am trying to create a table for the first instance of a duplicated <invoiceNum> element, and then add only the unique elements from successive product lines (<ProductID>, <ProductName>, <ProductDescription> etc.) and leave out the duplicated shipping information.

In the XML code snippet, you can see the layout of the XML. In the XSL snippet, I hope you can see how I am trying to construct the table. For each successive <invoices_snet> instance in the XML file, I want to add just the product information to the table through the transformation. Using for-each on the <invoices_snet> element simply creates a new table each time.

Should I use conditional logic here, compare the equality of the value of the <invoices_snet> element, use templates?

Your help is much appreciated!

   <database>    <invoices>     <invoices_snet>      <invoiceNum NAME="invoiceNum" TYPE="SMALLINT">368</invoiceNum>      <ProductID NAME="ProductID" TYPE="VARCHAR">SS106</ProductID>      <ProductName NAME="ProductName" TYPE="VARCHAR">Senna  Sunglasses</ProductName>      <ProductDescription NAME="ProductDescription" TYPE="VARCHAR">Lively sunglasses</ProductDescription>      <Quantity NAME="Quantity" TYPE="SMALLINT">34</Quantity>      <UnitPrice NAME="UnitPrice" TYPE="CURRENCY">40.0000</UnitPrice>      <ExtendedPrice NAME="ExtendedPrice" TYPE="CURRENCY">1360.0000</ExtendedPrice>      <contactName NAME="contactName" TYPE="VARCHAR">Jeff</contactName>      <shippingStreet NAME="shippingStreet" TYPE="VARCHAR">11 Acacia Avenue</shippingStreet>      <shippingCity NAME="shippingCity" TYPE="VARCHAR">Huddersfield</shippingCity>      <shippingCounty NAME="shippingCounty" TYPE="VARCHAR">Yorkshire</shippingCounty>      <shippingPostcode NAME="shippingPostcode" TYPE="VARCHAR">YO12 8LA</shippingPostcode>      <saleDate NAME="salesDate" TYPE="DATETIME">30. Mar. 16</saleDate>     </invoices_snet>     <invoices_snet>      <invoiceNum NAME="invoiceNum" TYPE="SMALLINT">368</invoiceNum>      <ProductID NAME="ProductID" TYPE="VARCHAR">SS368</ProductID>      <ProductName NAME="ProductName" TYPE="VARCHAR">Senna T-shirts</ProductName>      <ProductDescription NAME="ProductDescription" TYPE="VARCHAR">T-shirts of beige colour with cream piping</ProductDescription>      <Quantity NAME="Quantity" TYPE="SMALLINT">20</Quantity>      <UnitPrice NAME="UnitPrice" TYPE="CURRENCY">15.00</UnitPrice>      <ExtendedPrice NAME="ExtendedPrice" TYPE="CURRENCY">300.00</ExtendedPrice>      <contactName NAME="contactName" TYPE="VARCHAR">Jeff</contactName>      <shippingStreet NAME="shippingStreet" TYPE="VARCHAR">11 Acacia Avenue</shippingStreet>      <shippingCity NAME="shippingCity" TYPE="VARCHAR">Huddersfield</shippingCity>      <shippingCounty NAME="shippingCounty" TYPE="VARCHAR">Yorkshire</shippingCounty>      <shippingPostcode NAME="shippingPostcode" TYPE="VARCHAR">YO12 8LA</shippingPostcode>      <saleDate NAME="salesDate" TYPE="DATETIME">30. Mar. 16</saleDate>     </invoices_snet>    </invoices>   </database>          <?xml version="1.0" encoding="UTF-8"?>  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">      <xsl:template match="/database">          <html>              <head>                  <title>Invoice</title>                  <link rel="stylesheet" href="invoicingCSS.css"/>              </head>              <body>                  <h1>Invoice</h1>                  <br></br>                  <xsl:for-each select="invoices/invoices_snet">                  <h2>Order for Invoice Number: <xsl:value-of select="invoiceNum"/> </h2>                  <table>                      <tr>                          <th>Product ID</th>                          <th>Product Name</th>                          <th>Product Description</th>                          <th>Quantity</th>                          <th>Unit Price</th>                          <th>Extended Price</th>                          <th>Contact Name</th>                          <th>Shipping Address</th>                          <th>Sales Date</th>                      </tr>                          <tr>                              <td>                                  <xsl:value-of select="ProductID"/>                              </td>                              <td>                                  <xsl:value-of select="ProductName"/>                              </td>                              <td>                                  <xsl:value-of select="ProductDescription"/>                              </td>                              <td>                                  <xsl:value-of select="Quantity"/>                              </td>                              <td>                                  <xsl:value-of select="UnitPrice"/>                              </td>                              <td>                                  <xsl:value-of select="ExtendedPrice"/>                              </td>                              <td>                                  <xsl:value-of select="contactName"/>                              </td>                              <td>                                  <xsl:value-of select="concat(                                                      shippingStreet,' ',                                                      shippingCity,', ',                                                      shippingCounty,', ',                                                      shippingPostcode)"                                   />                              </td>                                                          <td>                                  <xsl:value-of select="saleDate"/>                              </td>                          </tr>                  </table>                  </xsl:for-each>              </body>          </html>      </xsl:template>  </xsl:stylesheet>    

No comments:

Post a Comment