Home > Net >  Im trying to create a XSL sheet Sum and Count function doesn't fetch result from a nested xml
Im trying to create a XSL sheet Sum and Count function doesn't fetch result from a nested xml

Time:12-12

  1. I am trying to create a xml file which gives me the expected output as below so basically my style sheet pulls data from xml based on few conditions which are as follows.
  2. The output should be fetched by passing in the cusid as a parameter so if I pass in cusid= a1234. (Please refer the xml file attached for details)
  3. Expected output is as below and it should be in a single root node meaning just the customer as below:

    <?xml version="1.0" encoding="UTF-8"?>
<customer name="Joe Malone"
          state="AZ"
          zip="45643"
          orders="2"
          number_items="8"/>
I'm Using XSL:1.0

  1. From the output above orders is the count of orders, so for cusid= a1234(from the xml file) we have 2 orders and number_items is the sum of the quantity(orders/order/inventory/quantity) for that particular cusid.
  2. So if I pass another cusid=z5678 as a parameter I should get the corresponding details to that cusid
  3. Attaching my attempt as well from which I am able to get the name,state and zip but it displays twice for a given cusid which Im not sure if my logic is incorrect (for loop).
  4. Also attaching the attempt to make the count and sum function work but doesn't fetch me the desired result. I am stuck at this point. Any inputs to fix this is much appreciated.

Here is my amazon.xsl file

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="cusid"/>
    <xsl:key name="data-by-cusid" match="customer" use="@cusid" />
        <xsl:template match="customers/customer">
            <xsl:variable name="customer-data" select="key('data-by-cusid', $cusid)" />
                         <xsl:for-each select="$customer-data">
                                <customer name= "{name}" state ="{state}" zip="{zip}" />
                         </xsl:for-each>
        </xsl:template>
</xsl:stylesheet>
This is the xml file amazonorder.xml

<?xml version="1.0" encoding="UTF-8"?>
<customers>
    <customer cusid="a1234">
        <name>Joe Malone</name>
        <state>AZ</state>
        <zip>45643</zip>
        <orders>
            <order oid="44470">
                <date>11/2/2021</date>
                <inventory id="p5148">
                    <description>Football</description>
                    <quantity>2</quantity>
                </inventory>
                <inventory id="sb2818">
                    <description>camping equipment</description>
                    <quantity>2</quantity>
                </inventory>
                <inventory id="c1215">
                    <description>light bulbs</description>
                    <quantity>2</quantity>
                </inventory>
            </order>
            <order oid="23421">
                <date>10/15/2020</date>
                <inventory id="lcb8876">
                    <description>Pillows</description>
                    <quantity>1</quantity>
                </inventory>
                <inventory id="bc9976">
                    <description>Mattress</description>
                    <quantity>1</quantity>
                </inventory>
            </order>
        </orders>
    </customer>
        <customer cusid="z5678">
            <name>Brandy Mccarthy</name>
            <state>CA</state>
            <zip>60144</zip>
            <orders>
                <order oid="12778">
                    <date>3/20/2021</date>
                    <inventory id="q4170">
                        <description>basketball</description>
                        <quantity>6</quantity>
                    </inventory>
                    <inventory id="cv6334">
                        <description>Shirts</description>
                        <quantity>2</quantity>
                    </inventory>
                    <inventory id="f7665">
                        <description>joggers</description>
                        <quantity>2</quantity>
                    </inventory>
                </order>
                <order oid="35679">
                    <date>8/8/2021</date>
                    <inventory id="mnc9933">
                        <description>camera</description>
                        <quantity>8</quantity>
                    </inventory>
                    <inventory id="zx1154">
                        <description>lamp</description>
                        <quantity>3</quantity>
                    </inventory>  
                    <inventory id="yu1484">
                        <description>bag</description>
                        <quantity>4</quantity>
                    </inventory>
                </order>
            </orders>
        </customer>
    </customers>

Here is my attempt for the count and sum functions which doesn't work (gives compilation errors)

 <xsl:template match="orders/order">
                <order count = "{count($data-by-orderid)}">
           <xsl:for-each select = "$data-by-orderid" >
               <xsl:select oid = "{$oid}" />
        </xsl:for-each>
                </order>
        </xsl:template> 

    <!--This is how I attempted to make the sum  work but this did not  workout for me to get the output as expected which I mentioned at the start of the post-->
        <xsl:template match="orders/order/inventory">
        <xsl:for-each select="orders/order/inventory">
            <Customer> 
                <TotalPurchase> 
                    <xsl:value-of select="sum(orders/order/inventory/quantity)"/>
                </TotalPurchase>
            </Customer>
        </xsl:for-each>
    </xsl:template>

CodePudding user response:

I believe you could do just this:

XSLT 1.0

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

<xsl:param name="cusid"/>

<xsl:key name="data-by-cusid" match="customer" use="@cusid" />

<xsl:template match="/">
    <xsl:variable name="customer" select="key('data-by-cusid', $cusid)" />
    <xsl:variable name="orders" select="$customer/orders/order" />
    <customer name="{$customer/name}" state="{$customer/state}" zip="{$customer/zip}" orders="{count($orders)}" number_items="{sum($orders/inventory/quantity)}"/>
</xsl:template>

</xsl:stylesheet>

Note that we are assuming each customer is unique in the input XML.

  • Related