Во входном файле in.xml мне нужно собрать все узлы PassengerType (может быть «взрослый», «дочерний») и сохранить теги BaseFare для каждого рейса (элементы Aircomp, но компонент «Налоги» должен быть добавлен как один общий узел - путем сложения каждого соответствующего Tax1 / Tax2 и создания общего узла Taxs.
in.xml
<?xml version='1.0' encoding='UTF-8'?>
<root>
<FareComponents>
<item>
<FareClass>F</FareClass>
<Fares>
<item>
<BaseFare>
<Amount>500.0</Amount>
<Currency>USD</Currency>
</BaseFare>
<PassengerType>Adult</PassengerType>
<Taxes>
<item>
<Tax>Tax1</Tax>
<Amount>
<Amount>200.0</Amount>
<Currency>USD</Currency>
</Amount>
</item>
<item>
<Tax>Tax2</Tax>
<Amount>
<Amount>1500.0</Amount>
<Currency>USD</Currency>
</Amount>
</item>
</Taxes>
</item>
</Fares>
<Flights>
<item>
<ArrivalDateTime>2012-07-21T08:25:00.000Z</ArrivalDateTime>
<DepartureDateTime>2012-07-21T07:20:00.000Z</DepartureDateTime>
<Origin>HHH</Origin>
<Destination>VVV</Destination>
<FlightLegs>
<FlightNumber>999</FlightNumber>
<CarrierCode>YY</CarrierCode>
</FlightLegs>
</item>
</Flights>
</item>
<item>
<FareClass>G</FareClass>
<Fares>
<item>
<BaseFare>
<Amount>500.0</Amount>
<Currency>USD</Currency>
</BaseFare>
<PassengerType>Adult</PassengerType>
<Taxes>
<item>
<Tax>Tax1</Tax>
<Amount>
<Amount>100.0</Amount>
<Currency>USD</Currency>
</Amount>
</item>
<item>
<Tax>Tax2</Tax>
<Amount>
<Amount>1500.0</Amount>
<Currency>USD</Currency>
</Amount>
</item>
</Taxes>
</item>
</Fares>
<Flights>
<item>
<ArrivalDateTime>2012-07-22T10:00:00.000Z</ArrivalDateTime>
<DepartureDateTime>2012-07-22T08:55:00.000Z</DepartureDateTime>
<Origin>VVV</Origin>
<Destination>HHH</Destination>
<FlightLegs>
<FlightNumber>888</FlightNumber>
<CarrierCode>YY</CarrierCode>
</FlightLegs>
</item>
</Flights>
</item>
</FareComponents>
</root>
Таким образом, для каждого компонента FareComponents / элемента я выбираю каждый набор тегов «Тарифы и рейсы» для соответствующего типа PassengerType (для взрослых, детей, младенцев) и создаю общий узел «Налоги», в котором суммируются отдельные Tax1 и Tax2 для каждого рейса
out.xml
<root>
<!-- Need to group the BaseFare and flights for the same PassengerType -->
<!-- and sum up the taxes Tax1 Tax2 as a combined element -->
<FareQuote>
<item>
<PassengerType>Adult</PassengerType>
<Fares>
<item>
<FareClass>F</FareClass>
<BaseFare>
<Amount>500.0</Amount>
<Currency>USD</Currency>
</BaseFare>
<Flights>
<item>
<ArrivalDateTime>2012-07-21T08:25</ArrivalDateTime>
<DepartureDateTime>2012-07-21T07:20</DepartureDateTime>
<Origin>HHH</Origin>
<Destination>VVV</Destination>
<FlightLegs>
<FlightNumber>999</FlightNumber>
<CarrierCode>YY</CarrierCode>
</FlightLegs>
</item>
</Flights>
</item>
<item>
<FareClass>G</FareClass>
<BaseFare>
<Amount>500.0</Amount>
<Currency>USD</Currency>
</BaseFare>
<Flights>
<item>
<ArrivalDateTime>2012-07-22T10:00</ArrivalDateTime>
<DepartureDateTime>2012-07-22T08:55</DepartureDateTime>
<Origin>VVV</Origin>
<Destination>HHH</Destination>
<FlightLegs>
<FlightNumber>888</FlightNumber>
<CarrierCode>YY</CarrierCode>
</FlightLegs>
</item>
</Flights>
</item>
<Taxes>
<item>
<TaxCode>AA</TaxCode>
<!-- AA corresponds to Tax1 -->
<Amount>
<Amount>300.0</Amount>
<Currency>USD</Currency>
</Amount>
</item>
<item>
<TaxCode>BB</TaxCode>
<!-- BB corresponds to Tax2 -->
<Amount>
<Amount>3000.0</Amount>
<Currency>USD</Currency>
</Amount>
</item>
</Taxes>
</Fares>
</item>
</FareQuote>
</root>
Использование следующего XML работает как таковое, но я не могу перенести PassengerType (Adult, Child, Infant) внутри for-each - поскольку он повторяет элементы в каждом запуске for-each. Я хочу, чтобы каждый PassengerType выводился только один раз для этого PassengerType.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output version="1.0" method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/root">
<xsl:element name="FareQuote">
<xsl:element name="item">
<!-- This needs to be for-each for the PassengerType, but how to have the inner loop -->
<!-- setting up for Adult for now -->
<xsl:element name="PassengerType">Adult</xsl:element>
<xsl:element name="Fares">
<xsl:for-each select="/root/FareComponents/item/Fares/item[PassengerType='Adult']">
<xsl:element name="item">
<xsl:element name="FareClass"><xsl:value-of select="../../FareClass"/></xsl:element>
<xsl:element name="BaseFare">
<xsl:element name="Amount"><xsl:value-of select="ceiling(BaseFare/Amount)"/></xsl:element>
<xsl:element name="Currency"><xsl:value-of select="BaseFare/Currency"/></xsl:element>
</xsl:element>
<xsl:element name="Flights">
<xsl:element name="item">
<xsl:element name="ArrivalDateTime"><xsl:value-of select="../../Flights/item/ArrivalDateTime"/></xsl:element>
<xsl:element name="DepartureDateTime"><xsl:value-of select="../../Flights/item/DepartureDateTime"/></xsl:element>
<xsl:element name="Origin"><xsl:value-of select="../../Flights/item/Origin"/></xsl:element>
<xsl:element name="Destination"><xsl:value-of select="../../Flights/item/Destination"/></xsl:element>
<xsl:element name="FlightLegs">
<xsl:element name="FlightNumber"><xsl:value-of select="../../Flights/FlightLegs/FlightNumber"/></xsl:element>
<xsl:element name="CarrierCode"><xsl:value-of select="../../Flights/FlightLegs/CarrierCode"/></xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:for-each>
<xsl:element name="Taxes">
<xsl:if test="sum(//Taxes/item[Tax='Tax1']/Amount/Amount) > 0">
<xsl:element name="item">
<xsl:element name="TaxCode">AA</xsl:element>
<xsl:element name="Amount">
<xsl:element name="Currency">INR</xsl:element>
<xsl:element name="Amount"><xsl:value-of select="sum(//Taxes/item[Tax='Tax1']/Amount/Amount)"/></xsl:element>
</xsl:element>
</xsl:element>
</xsl:if>
<xsl:if test="sum(//Taxes/item[Tax='Tax2']/Amount/Amount) > 0">
<xsl:element name="item">
<xsl:element name="TaxCode">BB</xsl:element>
<xsl:element name="Amount">
<xsl:element name="Currency">INR</xsl:element>
<xsl:element name="Amount"><xsl:value-of select="sum(//Taxes/item[Tax='Tax2']/Amount/Amount)"/></xsl:element>
</xsl:element>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>