Home > database >  How to select all attribute values in xslt from a xml document
How to select all attribute values in xslt from a xml document

Time:02-28

I have the following xml code:

<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="2021-05-20">
<Address Type="Shipping">
  <Name>Ellen Adams</Name>
  <Street>123 Maple Street</Street>
  <City>Mill Valley</City>
  <State>CA</State>
  <Zip>10999</Zip>
  <Country>USA</Country>
</Address>
<Address Type="Billing">
  <Name>Tai Yee</Name>
  <Street>8 Oak Avenue</Street>
  <City>Old Town</City>
  <State>PA</State>
  <Zip>95819</Zip>
  <Country>USA</Country>
</Address>
<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
<Items>
  <Item PartNumber="872-AA">
    <ProductName>Lawnmower</ProductName>
    <Quantity>1</Quantity>
    <Price curr="USD">148.95</Price>
    <Comment>Confirm this is electric</Comment>
    <Status> Shipped </Status>
  </Item>
  <Item PartNumber="926-AA">
    <ProductName>Baby Monitor</ProductName>
    <Quantity>2</Quantity>
    <Price curr="USD">39.98</Price>
    <ShipDate>2021-05-21</ShipDate>
    <Status> Shipped </Status>
  </Item>
</Items>

I want to display the PurchaseOrdeNo, OrderDate, PartNumber. I am using the following code

<xsl:template match="/">

  <html>
     <head>
        <title>Purchase Order</title>
        <style>
            
           table, th, td {
              border: 1px solid black;
              border-collapse: collapse;
           }

            th {
                background-color: lavender;
            }

            td,th {
                padding: 10px;
            }

        </style>
     </head>

     <body>
     <table border='1'>
     <tr>
                    <th>PurchaseOrderNumber</th>
                    <th>OrderDate</th>
                    <th>PartNumber</th>
                    </tr>
     <xsl:for-each select="//PurchaseOrder">
     <tr>
     <td><xsl:value-of select="@PurchaseOrderNumber"/> </td>
     <td><xsl:value-of select="@OrderDate"/> </td>
    <td>
        <ul>
            <li> <xsl:value-of select="Items/Item/@PartNumber"/> </li>
            <br/>
        </ul>
    </td>
     </tr>
     </xsl:for-each>
     </table>
     </body>
  </html>
</xsl:template>

I am trying to display all the PartNumber for each PurchaseOrderNumber, but the output is only displaying one PartNumber per each entry. I tried everything, but it's not working. What should I do?

CodePudding user response:

Please try the following XSLT.

XSLT 1.0

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>Purchase Order</title>
                <style>table, th, td {
              border: 1px solid black;
              border-collapse: collapse;
           }

            th {
                background-color: lavender;
            }

            td,th {
                padding: 10px;
            }</style>
            </head>

            <body>
                <table border="1">
                    <thead>
                        <tr>
                            <th>PurchaseOrderNumber</th>
                            <th>OrderDate</th>
                            <th>PartNumber</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each select="/PurchaseOrder">
                            <tr>
                                <td>
                                    <xsl:value-of select="@PurchaseOrderNumber"/>
                                </td>
                                <td>
                                    <xsl:value-of select="@OrderDate"/>
                                </td>
                                <td>
                                    <ul>
                                        <xsl:for-each select="Items/Item">
                                            <li>
                                                <xsl:value-of select="@PartNumber"/>
                                            </li>
                                        </xsl:for-each>
                                    </ul>
                                </td>
                            </tr>
                        </xsl:for-each>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

CodePudding user response:

Since it seems you use an unordered list nested inside an HTML table cell, you intend to list all part numbers as bullet points. Therefore, consider running the xsl:for-each on each individual <Item>.

Alternatively, as demonstrated below use multiple templates for each level without xsl:for-each. Should there be a different root where XML maintains multiple <PurchaseOrder> nodes, adjust first template match to /root.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/">
        <html>
            <head>
                <title>Purchase Order</title>
                <style>table, th, td {
              border: 1px solid black;
              border-collapse: collapse;
           }

            th {
                background-color: lavender;
            }

            td,th {
                padding: 10px;
            }</style>
            </head>

            <body>
                <table border="1">
                    <thead>
                        <tr>
                            <th>PurchaseOrderNumber</th>
                            <th>OrderDate</th>
                            <th>PartNumber</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:apply-templates select="PurchaseOrder"/>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
    
    <xsl:template match="PurchaseOrder">
       <tr>
          <td><xsl:value-of select="@PurchaseOrderNumber"/></td>
          <td><xsl:value-of select="@OrderDate"/></td>
          <td>
              <ul><xsl:apply-templates select="Items/Item"/></ul>
          </td>
      </tr>
    </xsl:template>
    
    <xsl:template match="Item">
      <li><xsl:value-of select="@PartNumber"/></li>
    </xsl:template>
    
</xsl:stylesheet>

XSLT HTML Output

  • Related