Home > Mobile >  XSLT - Create Multiple Tables based on Child Node Value
XSLT - Create Multiple Tables based on Child Node Value

Time:11-27

Here is the source XML code:

<customers>
 <customer cid="c5391">
      <name>Evans, Terry</name>
      <street>641 Greenway Blvd.</street>
      <city>Mount Hope</city>
      <state>OH</state>
      <zip>44660</zip>
      <orders>
         <order oid="52517">
            <date>8/1/2017</date>
            <item iid="wb7133">
               <description>Insulated Water Bottle</description>
               <qty>2</qty>
            </item>
            <item iid="gps1015">
               <description>Zendo GPS meter</description>
               <qty>1</qty>
            </item>
            <item iid="bl2815">
               <description>Boot Laces (Medium)</description>
               <qty>1</qty>
            </item>
            <item iid="tr8140">
               <description>Trail Mix (Pouch)</description>
               <qty>5</qty>
            </item>
            <item iid="fa8442">
               <description>First Aid Kit (Pack Size)</description>
               <qty>1</qty>
            </item>
            <item iid="bb7117">
               <description>Blister Patches</description>
               <qty>3</qty>
            </item>
         </order>
         <order oid="53003">
            <date>8/5/2017</date>
            <item iid="hp7814">
               <description>Fiberglass Light Hiking Poles (Spring Adj.)</description>
               <qty>1</qty>
            </item>
         </order>
         <order oid="54814">
            <date>8/6/2017</date>
            <item iid="sb6601">
               <description>Solar Battery Recharging Unit</description>
               <qty>1</qty>
            </item>
            <item iid="br9002">
               <description>Bug Repellent (Deep Woodes)</description>
               <qty>2</qty>
            </item>
            <item iid="sb8502">
               <description>Sunblock SPF 30 (Hiking Size)</description>
               <qty>6</qty>
            </item>
         </order>
      </orders>
   </customer>
</customers>

I am trying to use XSL/HTML/CSS to reformat the code to look like below: enter image description here

Here is my code, I am trying to create different order tables for each order (listed in descending order by order ID as shown in the sample photo above). Also, each order table should include the date of the order and the order ID:

    <table>
    
    <tr>
        <th>Item No.</th>
        <th>Description</th>
        <th>Qty</th>

    </tr>

    <xsl:for-each select="//order/item" group-by="date">
        <xsl:sort select="order/@oid" data-type="number" order="descending"/>
        <tr>
            <td>
                <xsl:value-of select="@iid"></xsl:value-of>
            </td>
            <td>
                <xsl:value-of select="description"></xsl:value-of>
            </td>
            <td>
                <xsl:value-of select="qty"></xsl:value-of>
            </td>
        </tr>
    </xsl:for-each>
    </table>

The result look like below.

enter image description here

Right now my code is returning all the items, but I need to create multiple tables based for each order, which I am not sure how to do.

CodePudding user response:

I am guessing (!) you want to do something like this:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/customers">
    <html>
        <body>
            <xsl:for-each select="customer/orders/order">
                <!-- sort by date ??? -->
                <table border="1">
                    <!-- header -->
                    <tr>
                        <td>
                            <xsl:value-of select="date"/>
                        </td>
                        <td/>
                        <td>
                            <xsl:value-of select="@oid"/>
                        </td>
                    </tr>
                    <tr>
                        <th>Item No.</th>
                        <th>Description</th>
                        <th>Qty</th>
                    </tr>
                    <!-- body -->
                    <xsl:for-each select="item">
                        <tr>
                            <td>
                                <xsl:value-of select="@iid"/>
                            </td>
                            <td>
                                <xsl:value-of select="description"/>
                            </td>
                            <td>
                                <xsl:value-of select="qty"/>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </xsl:for-each>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

Applied to your XML example, this would produce:

Result

<html>
   <body>
      <table border="1">
         <tr>
            <td>8/1/2017</td>
            <td></td>
            <td>52517</td>
         </tr>
         <tr>
            <th>Item No.</th>
            <th>Description</th>
            <th>Qty</th>
         </tr>
         <tr>
            <td>wb7133</td>
            <td>Insulated Water Bottle</td>
            <td>2</td>
         </tr>
         <tr>
            <td>gps1015</td>
            <td>Zendo GPS meter</td>
            <td>1</td>
         </tr>
         <tr>
            <td>bl2815</td>
            <td>Boot Laces (Medium)</td>
            <td>1</td>
         </tr>
         <tr>
            <td>tr8140</td>
            <td>Trail Mix (Pouch)</td>
            <td>5</td>
         </tr>
         <tr>
            <td>fa8442</td>
            <td>First Aid Kit (Pack Size)</td>
            <td>1</td>
         </tr>
         <tr>
            <td>bb7117</td>
            <td>Blister Patches</td>
            <td>3</td>
         </tr>
      </table>
      <table border="1">
         <tr>
            <td>8/5/2017</td>
            <td></td>
            <td>53003</td>
         </tr>
         <tr>
            <th>Item No.</th>
            <th>Description</th>
            <th>Qty</th>
         </tr>
         <tr>
            <td>hp7814</td>
            <td>Fiberglass Light Hiking Poles (Spring Adj.)</td>
            <td>1</td>
         </tr>
      </table>
      <table border="1">
         <tr>
            <td>8/6/2017</td>
            <td></td>
            <td>54814</td>
         </tr>
         <tr>
            <th>Item No.</th>
            <th>Description</th>
            <th>Qty</th>
         </tr>
         <tr>
            <td>sb6601</td>
            <td>Solar Battery Recharging Unit</td>
            <td>1</td>
         </tr>
         <tr>
            <td>br9002</td>
            <td>Bug Repellent (Deep Woodes)</td>
            <td>2</td>
         </tr>
         <tr>
            <td>sb8502</td>
            <td>Sunblock SPF 30 (Hiking Size)</td>
            <td>6</td>
         </tr>
      </table>
   </body>
</html>

which before adding any styling would render as:

enter image description here

I left out the sorting part, because (a) I don't know what is the date format of the input and (b) the orders seem to be already sorted by date anyway.

  • Related