Reputation: 1708
I am beginner in XSLT 1.0. I am facing an issue when i tried to find unique node with Highest value.
Source XML:
<Response>
<Flight>
<From>A</From>
<To>B</To>
<Passengers>
<Passenger>
<Fare>200</Fare>
<Fee>15</Fee>
<Type>ADT</Type>
</Passenger>
<Passenger>
<Fare>200</Fare>
<Fee>15</Fee>
<Type>ADT</Type>
</Passenger>
<Passenger>
<Fare>150</Fare>
<Fee>15</Fee>
<Type>CHD</Type>
</Passenger>
</Passengers>
</Flight>
<Flight>
<From>B</From>
<To>A</To>
<Passengers>
<Passenger>
<Fare>250</Fare>
<Fee>25</Fee>
<Type>ADT</Type>
</Passenger>
<Passenger>
<Fare>250</Fare>
<Fee>25</Fee>
<Type>ADT</Type>
</Passenger>
<Passenger>
<Fare>100</Fare>
<Fee>25</Fee>
<Type>CHD</Type>
</Passenger>
</Passengers>
</Flight>
</Response>
As shown in above XML, There is a round trip result for A-B origin destination and i am going to purchase tickets for both the flights. i need to calculate total fare, fee (whichever is highest from both the Flights) and its total price.
Expected Output:
<Result>
<PassengerGroup TotalFare="1150" TotalFee="75" TotalPrice="1225"/>
</Result>
Here,
TotalFare
is sum of all the Fare
tag.TotalFee
is greater value of each passenger type multiply by no of passenger of that type.TotalPrice
is sum of ToatalFare
and TotalFee
attribute.I've tried with below XSLT.
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Response">
<xsl:element name="Result">
<xsl:element name="PassengerGroup">
<xsl:attribute name="TotalFare">
<xsl:value-of select="sum(//Flight/Passengers/Passenger/Fare)"/>
</xsl:attribute>
<xsl:attribute name="TotalFee">
<xsl:value-of select="sum(//Flight/Passengers/Passenger[not(Type=preceding::Passenger/Type)]/Fee)"/>
</xsl:attribute>
<xsl:attribute name="TotalFee">
<xsl:value-of select="sum(//Flight/Passengers/Passenger/Fare) + sum(//Flight/Passengers/Passenger/Fee)"/>
</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
and got the below output.
Output:
<Result>
<PassengerGroup TotalFare="1150" TotalFee="30" TotalPrice="1270"/>
</Result>
TotalFee
is not calculated correctly. Please Help. Thanks.
Upvotes: 0
Views: 993
Reputation: 101730
I believe this should do it:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:exslt="http://exslt.org/common" exclude-result-prefixes="exslt">
<xsl:output method="xml" indent="yes" />
<xsl:key name="kPassenger" match="Passenger" use="Type" />
<!-- The passenger nodes from just the first flight, so we can count how many of
each type there are -->
<xsl:variable name="passengers" select="Response/Flight[1]/Passengers/Passenger" />
<xsl:template match="Response">
<xsl:variable name="totalFare" select="sum(Flight/Passengers/Passenger/Fare)" />
<xsl:variable name="feeByPassenger">
<xsl:apply-templates
select="$passengers[generate-id() =
generate-id(key('kPassenger', Type)[1])]"
mode="fee" />
</xsl:variable>
<xsl:variable name="totalFee"
select="sum(exslt:node-set($feeByPassenger)/*/@value)" />
<Result>
<PassengerGroup TotalFare="{$totalFare}" TotalFee="{$totalFee}"
TotalPrice="{$totalFare + $totalFee}" />
</Result>
</xsl:template>
<xsl:template match="Passenger" mode="fee">
<xsl:variable name="maxFee">
<xsl:apply-templates select="key('kPassenger', Type)/Fee">
<xsl:sort select="." data-type="number" order="descending"/>
</xsl:apply-templates>
</xsl:variable>
<fee value="{$maxFee * count($passengers[Type = current()/Type])}"/>
</xsl:template>
<xsl:template match="Fee">
<xsl:if test="position() = 1">
<xsl:value-of select="." />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When run on your sample input, the result is:
<Result>
<PassengerGroup TotalFare="1150" TotalFee="75" TotalPrice="1225" />
</Result>
Upvotes: 0