- 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.
- 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)
- 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
- 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.
- So if I pass another cusid=z5678 as a parameter I should get the corresponding details to that cusid
- 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).
- 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.