Hi All, I am kind of find it difficult to build my (xslt 1) template:

I have this following XML input:

    <Ticket>

      <ItineraryItem>
                    <Flight ArrivalDateTime="2012-08-31T09:40:00" DepartureDateTime="2012-08-31T06:00:00" DirectionInd="Outbound">
                        <DepartureAirport LocationCode="BRN"/>
                        <ArrivalAirport LocationCode="ZTH"/>
                        <OperatingAirline Code="2L" FlightNumber="5320"/>
                    </Flight>
                </ItineraryItem>
                <ItineraryItem>
                    <Flight ArrivalDateTime="2012-09-14T11:00:00" DepartureDateTime="2012-09-14T10:15:00" DirectionInd="Inbound">
                        <DepartureAirport LocationCode="ZTH"/>
                        <ArrivalAirport LocationCode="CFU"/>
                        <OperatingAirline Code="2L" FlightNumber="5321"/>
                    </Flight>
                </ItineraryItem>
                <ItineraryItem>
                    <Flight ArrivalDateTime="2012-09-14T12:40:00" DepartureDateTime="2012-09-14T11:40:00" DirectionInd="Inbound">
                        <DepartureAirport LocationCode="CFU"/>
                        <ArrivalAirport LocationCode="BRN"/>
                        <OperatingAirline Code="2L" FlightNumber="5321"/>
                    </Flight>
                </ItineraryItem>


    </Ticket>

And Have built the following template (xslt 1):

    <xsl:template match="ota:Flight">
            <xsl:variable name="direction" select="@DirectionInd"/>
            <Fat ServiceType="T">
                <xsl:attribute name="SegRef">
                    <xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/>
                    <xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/>
                </xsl:attribute>
                <xsl:if test="../@Key">
                    <xsl:attribute name="Key">
                        <xsl:choose>
                            <xsl:when test="ota:CabinAvailability/ota:Seat/@Code">
                                <xsl:variable name="code" select="ota:CabinAvailability/ota:Seat/@Code"/>
                                <xsl:value-of select="concat(substring(../@Key, 1, 10), $code, substring(../@Key, 12))"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="../@Key"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:attribute>
                </xsl:if>
                <StartDate>
                    <xsl:value-of select="datetime:format-date(substring(@DepartureDateTime, 1, 10), 'ddMMyyyy')"/>
                </StartDate>
                <Dep>
                    <xsl:value-of select="ota:DepartureAirport/@LocationCode"/>
                </Dep>
                <Arr>
                    <xsl:value-of select="ota:ArrivalAirport/@LocationCode"/>
                </Arr>
                <Persons>
                    <xsl:value-of select="translate(ota:CabinAvailability/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
                </Persons>
            </Fat>

And it generates the following output:

    <Request>
        <Fat ServiceType="T" SegRef="000">
            <StartDate>31082012</StartDate>
            <Dep>BRN</Dep>
            <Arr>ZTH</Arr>
            <Persons>12</Persons>
        </Fat>
        <Fat ServiceType="T" SegRef="001">
            <StartDate>14092012</StartDate>
            <Dep>ZTH</Dep>
            <Arr>CFU</Arr>
            <Persons>12</Persons>
        </Fat>
        <Fat ServiceType="T" SegRef="002">
            <StartDate>14092012</StartDate>
            <Dep>CFU</Dep>
            <Arr>BRN</Arr>
            <Persons>12</Persons>
        </Fat>
    </Request>

Whereas I want an output to be like this:

    <Request>
        <Fat ServiceType="T" SegRef="000">
            <StartDate>31082012</StartDate>
            <Dep>BRN</Dep>
            <Arr>ZTH</Arr>
            <Persons>12</Persons>
        </Fat>
        <Fat ServiceType="T" SegRef="001">
            <StartDate>14092012</StartDate>
            <Dep>ZTH</Dep>
            <Arr>BRN</Arr>
            <Persons>12</Persons>
        </Fat>
    </Request>

That is to skip the intermediate flight, but only the start and end airports. In this above case, The outbound flight is fine, but there are 2 Inbound flights. I just want the starting Inbound airport and the final Inbound airport in the return flight. Similarly, there could be a scenario, where I have 2 Outbound flight, in that case the scenario woulc be the same that is the first Outboud flight and last Outboud flight. Normal scenario with single Outbound and Inbound flight are only covered at the moment by my template above. That case should stay as it is in the revised template. Your help in this regard should be highlly appreciated.

Thanks.

Dani AI

Generated

Brief summary and the root cause (why last() looked broken)
When you have several Flight elements spread over multiple ItineraryItem parents, XPath’s position() and last() are evaluated against the current node‑set in the current context. That means a predicate like [last()] can end up being evaluated per parent or per step and not against the global list of all directional flights you intended. The symptom is exactly what saw: the “last” arrival came out wrong because last() was being applied in the wrong context.

Recommended, XSLT‑1.0‑safe pattern (no engine extensions required)
First gather the flights for the direction into a single node set (a variable or a template parameter). Once the node-set is bound in one context you can reliably use the ordinal selectors (first = [1], last = [last()]) against that set to read the starting departure and final arrival. If the XML ordering isn’t reliable, sort that node-set by the timestamp before picking the first/last. In XSLT 1.0 the usual choices are: bind via xsl:variable select="..." and then reference $set[1] / $set[last()], or pass the bound set into a named template and use the parameter inside the template (that is the approach used successfully).

Practical tips and small optimizations
Avoid repeatedly evaluating document-wide expressions like //ota:CabinAvailability... — capture passenger RPHs once and reuse a variable. Increment the SegRef/counter only when emitting a condensed Fat element to keep numbering contiguous. For more complex grouping (many directions, mixed legs) consider Muenchian grouping in XSLT 1.0 or upgrading to XSLT 2.0 (for-each-group / subsequence) which makes first/last-after-grouping simpler. Credit to for steering toward selecting first/last separately and to for the final node-set→template solution that resolves the last() scoping issue.

Recommended Answers

All 9 Replies

Can we see your full XSLT, can't edit it currently due to missing declarations allowing the functionality.

I don't know if the entire xslt scrip would help, but anyway here it is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:datetime="" xmlns:ota="http://www.opentravel.org/OTA/2003/05" xmlns:java="java" xmlns:dyn="http://exslt.org/dynamic" xmlns:func="" xmlns:function="http://function.com" xmlns:exslt="" exclude-result-prefixes="xsl datetime ota java dyn func function exslt">
    <xsl:import href="common.xsl"/>
    <xsl:param name="rph_pos" select="java:text.ParsePosition.new(0)"/>
    <xsl:param name="sysdate" select="datetime:date-time()"/>
    <xsl:param name="sterminalid" select="java:lang.System.currentTimeMillis ()"/>
    <xsl:param name="profile"/>
    <xsl:param name="profileNode" select="exslt:node-set($profile)"/>
    <xsl:param name="usercode" select="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:UniqueID[@Type ='99']/@ID"/>
    <xsl:param name="request_root"/>
    <xsl:variable name="request_rootNode" select="exslt:node-set($request_root)"/>
    <xsl:param name="packageFlight"/>
    <xsl:variable name="packageNode" select="exslt:node-set($packageFlight)"/>
    <!--Find the Language ID-->
    <xsl:variable name="BrandCode">
        <xsl:value-of select="//ota:PackageRequest/@BrandCode"/>
    </xsl:variable>
    <xsl:variable name="LangID">
        <xsl:choose>
            <xsl:when test="//@PrimaryLangID">
                <xsl:value-of select="translate(//@PrimaryLangID,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
            </xsl:when>
            <xsl:when test="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:Profile[@ProfileType='CUS']/ota:PrefCollections/ota:PrefCollection/ota:CommonPref[@PrimaryLangID]">
                <xsl:value-of select="translate($profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:Profile[@ProfileType='CUS']/ota:PrefCollections/ota:PrefCollection/ota:CommonPref/@PrimaryLangID,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
            </xsl:when>
            <xsl:when test="//@AltLangID">
                <xsl:value-of select="translate(//@AltLangID,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
            </xsl:when>
            <xsl:when test="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:Profile[@ProfileType='CUS']/ota:PrefCollections/ota:PrefCollection/ota:CommonPref[@AltLangID]">
                <xsl:value-of select="translate($profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:Profile[@ProfileType='CUS']/ota:PrefCollections/ota:PrefCollection/ota:CommonPref/@AltLangID,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
            </xsl:when>
            <xsl:otherwise>EN</xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:template name="header">
        <xsl:param name="target"/>
        <xsl:param name="langid"/>
        <xsl:param name="user_name"/>
        <xsl:param name="brand_code">
            <xsl:value-of select="//ota:PackageRequest/@BrandCode"/>
        </xsl:param>
        <xsl:variable name="agent" select="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo[ota:UniqueID/@Type ='11' and ota:UniqueID/@ID =$brand_code ]/ota:Profile/ota:UserID[@ID_Context = 'agencyCode']/@ID"/>
        <xsl:attribute name="Version">2.5</xsl:attribute>
        <xsl:attribute name="From">xxx</xsl:attribute>
        <xsl:attribute name="To">xxx</xsl:attribute>
        <xsl:attribute name="TermId">xx<xsl:value-of select="substring($sterminalid,string-length($sterminalid) - 3 )"/><!--xsl:value-of select="$sterminalid"/--></xsl:attribute>
        <xsl:attribute name="Window">A</xsl:attribute>
        <xsl:attribute name="Date"><xsl:value-of select="datetime:format-date($sysdate, 'ddMMyyyy')"/></xsl:attribute>
        <xsl:attribute name="Time"><xsl:value-of select="datetime:format-date($sysdate, 'HHmmss')"/></xsl:attribute>
        <xsl:attribute name="Confirm">xxx</xsl:attribute>
        <xsl:choose>
            <xsl:when test="//@Agent">
                <xsl:attribute name="Agent"><xsl:value-of select="//@Agent"/></xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="Agent"><xsl:value-of select="$agent"/></xsl:attribute>
            </xsl:otherwise>
        </xsl:choose>
        <!--xsl:value-of select="$agent"/-->
        <xsl:attribute name="Lang"><xsl:choose><xsl:when test="$langid"><xsl:value-of select="$langid"/></xsl:when><xsl:otherwise><xsl:value-of select="'DE'"/></xsl:otherwise></xsl:choose></xsl:attribute>
        <xsl:attribute name="UserCode">xx</xsl:attribute>
        <xsl:attribute name="UserType">x</xsl:attribute>
        <xsl:choose>
            <xsl:when test="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo[ota:UniqueID/@Type ='11' and ota:UniqueID/@ID =$brand_code ]/ota:Profile/ota:UserID[@ID_Context = 'agentCode']/@ID">
                <xsl:attribute name="UserName"><xsl:value-of select="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo[ota:UniqueID/@Type ='11' and ota:UniqueID/@ID =$brand_code ]/ota:Profile/ota:UserID[@ID_Context = 'agentCode']/@ID"/></xsl:attribute>
            </xsl:when>
            <xsl:when test="$user_name">
                <xsl:attribute name="UserName"><xsl:value-of select="$user_name"/></xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="UserName">xxx</xsl:attribute>
            </xsl:otherwise>
        </xsl:choose>
        <!--xsl:value-of select="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:Profile/ota:UserID/CompanyName/@CompanyShortName"/-->
        <xsl:attribute name="UserFirstName">CH</xsl:attribute>
        <!--xsl:value-of select="$profileNode/ota:OTA_TT_ProfileReadRS/ota:Profiles/ota:ProfileInfo/ota:Profile/ota:UserID/CompanyName/@Code"/-->
        <xsl:choose>
            <xsl:when test="$target">
                <xsl:call-template name="Mode">
                    <xsl:with-param name="targetType" select="$target"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$profileNode/ota:OTA_TT_ProfileReadRS/@Target">
                <xsl:call-template name="Mode">
                    <xsl:with-param name="targetType" select="$profileNode/ota:OTA_TT_ProfileReadRS/@Target"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="Mode">
                    <xsl:with-param name="targetType">Test</xsl:with-param>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="ota:PackageRequest">
        <TOCode>
            <xsl:value-of select="function:translateBrandCode(@BrandCode)"/>
        </TOCode>
        <Catalog>
            <xsl:value-of select="@TravelCode"/>
        </Catalog>
        <CETSRef>xx</CETSRef>
        <Creator>xx</Creator>
        <!--xsl:apply-templates select="ota:DateRange" mode="enddate"/-->
        <xsl:choose>
            <xsl:when test="@TourCode">
                <Fac ServiceType="P">
                    <StartDate>
                        <xsl:value-of select="datetime:format-date(ota:DateRange/@Start, 'ddMMyyyy')"/>
                    </StartDate>
                    <Duration>
                        <xsl:choose>
                            <xsl:when test="ota:DateRange/@Duration">
                                <xsl:value-of select="substring-before(substring-after(ota:DateRange/@Duration, 'P'), 'D')"/>
                            </xsl:when>
                            <xsl:when test="ota:DateRange/@End">
                                <xsl:value-of select="function:getDuration(ota:DateRange/@Start, ota:DateRange/@End, 'yyyy-MM-dd')"/>
                            </xsl:when>
                        </xsl:choose>
                    </Duration>
                    <Product>
                        <xsl:value-of select="@TourCode"/>
                    </Product>
                </Fac>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']"/>
                <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']"/>
                <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Accommodation"/>
                <!-- xsl:apply-templates select="ota:Extras"/-->
                <!-- building fake hotel -->
                <xsl:if test="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/@DummyAccommodation">
                    <xsl:call-template name="buildFakeHotel"/>
                </xsl:if>
                <xsl:call-template name="Insurance">
                    <xsl:with-param name="persons" select="//ota:PassengerRPHs/@ListOfPassengerRPH"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="Insurance">
        <xsl:param name="persons"/>
        <Fac ServiceType="V">
            <xsl:if test="@Key">
                <xsl:attribute name="Key"><xsl:value-of select="@Key"/></xsl:attribute>
            </xsl:if>
            <xsl:attribute name="SegRef"><xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos))"/><xsl:value-of select="format-number(java:getIndex($rph_pos),'000.#')"/></xsl:attribute>
            <Code>KV</Code>
            <TextS>Keine Annullationsversicherung</TextS>
            <Persons>
                <xsl:value-of select="translate($persons,' ', '')"/>
            </Persons>
        </Fac>
    </xsl:template>
    <xsl:template match="ota:DateRange" mode="enddate">
        <StartDate>
            <xsl:value-of select="datetime:format-date(@Start, 'ddMMyyyy')"/>
        </StartDate>
        <EndDate>
            <xsl:value-of select="datetime:format-date(@End, 'ddMMyyyy')"/>
        </EndDate>
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="ota:Flight">
        <xsl:variable name="direction" select="@DirectionInd"/>
        <Fat ServiceType="T">
            <!--xsl:if test="../@Status = 'OnRequest'">
                <xsl:attribute name="ConfirmRQ">Y</xsl:attribute>
            </xsl:if-->
            <xsl:attribute name="SegRef"><xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/><xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/></xsl:attribute>
            <xsl:if test="../@Key">
                <xsl:attribute name="Key"><xsl:choose><xsl:when test="ota:CabinAvailability/ota:Seat/@Code"><xsl:variable name="code" select="ota:CabinAvailability/ota:Seat/@Code"/><xsl:value-of select="concat(substring(../@Key, 1, 10), $code, substring(../@Key, 12))"/></xsl:when><xsl:otherwise><xsl:value-of select="../@Key"/></xsl:otherwise></xsl:choose></xsl:attribute>
            </xsl:if>
            <!--xsl:attribute name="Direction">
                <xsl:choose>
                    <xsl:when test="@DirectionInd= 'Outbound'">H</xsl:when>
                    <xsl:when test="@DirectionInd= 'Inbound'">R</xsl:when>
                </xsl:choose>
            </xsl:attribute-->
            <StartDate>
                <xsl:value-of select="datetime:format-date(substring(@DepartureDateTime, 1, 10), 'ddMMyyyy')"/>
            </StartDate>
            <!--xsl:if test="@DirectionInd= 'Outbound'">
                <Duration>
                    <xsl:choose>
                        <xsl:when test="//ota:PackageRequest/ota:DateRange/@Duration">
                            <xsl:value-of select="substring-before(substring-after(//ota:PackageRequest/ota:DateRange/@Duration, 'P'), 'D')"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="function:getDuration(//ota:PackageRequest/ota:DateRange/@Start, //ota:PackageRequest/ota:DateRange/@End, 'yyyy-MM-dd')"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </Duration>
            </xsl:if-->
            <Dep>
                <xsl:value-of select="ota:DepartureAirport/@LocationCode"/>
            </Dep>
            <Arr>
                <xsl:value-of select="ota:ArrivalAirport/@LocationCode"/>
            </Arr>
            <!--     <Carrier>  -->
            <!--xsl:value-of select="ota:OperatingAirline/@Code"/-->
            <!-- </Carrier>  -->
            <!-- <FlightNr> -->
            <!--xsl:value-of select="ota:OperatingAirline/@FlightNumber"/-->
            <!-- </FlightNr> -->
            <!--xsl:if test="ota:CabinAvailability/ota:Seat/@CodeContext">
                <Class>
                    <xsl:value-of select="ota:CabinAvailability/ota:Seat/@CodeContext"/>
                </Class>
            </xsl:if-->
            <!--xsl:if test="@TravelCode">
                <Chain>
                    <xsl:value-of select="@TravelCode"/>
                </Chain>
            </xsl:if-->
            <!--xsl:apply-templates select="ota:CabinAvailability"/-->
            <Persons>
                <xsl:value-of select="translate(ota:CabinAvailability/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
            </Persons>
            <!--xsl:apply-templates select="ota:FlightSegments"/-->
        </Fat>
    </xsl:template>
    <!--xsl:template match="ota:FlightSegments">
        <xsl:apply-templates select="ota:FlightSegment"/>
    </xsl:template-->
    <!--xsl:template match="ota:FlightSegment">
        <Leg External="Y">
            <xsl:attribute name="Key">
                <xsl:value-of select="@InfoSource"/>
            </xsl:attribute>
            <DepDate>
                <xsl:value-of select="datetime:format-date(substring-before(@DepartureDateTime, 'T'), 'ddMMyyyy')"/>
            </DepDate>
            <ArrDate>
                <xsl:value-of select="datetime:format-date(substring-before(@ArrivalDateTime, 'T'), 'ddMMyyyy')"/>
            </ArrDate>
            <Dep>
                <xsl:value-of select="ota:DepartureAirport/@LocationCode"/>
            </Dep>
            <Arr>
                <xsl:value-of select="ota:ArrivalAirport/@LocationCode"/>
            </Arr>
            <Class>
                <xsl:value-of select="../../ota:CabinAvailability/ota:Seat/@Code"/>
            </Class>
            <Carrier>
                <xsl:value-of select="ota:OperatingAirline/@Code"/>
            </Carrier>
            <FlightNr>
                <xsl:value-of select="ota:OperatingAirline/@FlightNumber"/>
            </FlightNr>
            <DepTime>
                <xsl:value-of select="datetime:format-date(@DepartureDateTime, 'HHmm')"/>
            </DepTime>
            <ArrTime>
                <xsl:value-of select="datetime:format-date(@ArrivalDateTime, 'HHmm')"/>
            </ArrTime>
        </Leg>
    </xsl:template-->
    <!--xsl:template match="ota:CabinAvailability">
        <xsl:variable name="allocation" select="translate(ota:PassengerRPHs/@ListOfPassengerRPH, ' ', ',')"/>
        <xsl:call-template name="PersonAssignment">
            <xsl:with-param name="allocation" select="$allocation"/>
        </xsl:call-template>
    </xsl:template-->
    <xsl:template match="ota:Accommodation">
        <Fah ServiceType="H">
            <!--xsl:if test="../@Status = 'OnRequest'">
                <xsl:attribute name="ConfirmRQ">Y</xsl:attribute>
            </xsl:if-->
            <xsl:attribute name="SegRef"><xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/><xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/></xsl:attribute>
            <!--xsl:if test="../@Key">
                <xsl:attribute name="Key">
                    <xsl:value-of select="../@Key"/>
                </xsl:attribute>
            </xsl:if-->
            <xsl:apply-templates select="ota:DateRange" mode="duration"/>
            <Destination>
                <xsl:value-of select="substring(ota:RoomProfiles/ota:RoomProfile/@BookingCode,1,3)"/>
                <!--xsl:value-of select="@DestinationCode"/-->
            </Destination>
            <xsl:apply-templates select="ota:RoomProfiles"/>
            <xsl:apply-templates select="ota:MealPlans"/>
            <Persons>
                <xsl:value-of select="translate(ota:RoomProfiles/ota:RoomProfile/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
            </Persons>
            <!--xsl:variable name="allocation" select="translate(ota:RoomProfiles/ota:RoomProfile/ota:PassengerRPHs/@ListOfPassengerRPH,' ', ',')"/-->
            <!--xsl:call-template name="PersonAssignment">
                <xsl:with-param name="allocation" select="$allocation"/>
            </xsl:call-template-->
        </Fah>
    </xsl:template>
    <xsl:template match="ota:DateRange" mode="duration">
        <StartDate>
            <xsl:value-of select="datetime:format-date(@Start, 'ddMMyyyy')"/>
        </StartDate>
        <Duration>
            <xsl:value-of select="function:getDuration(@Start, @End, 'yyyy-MM-dd')"/>
        </Duration>
    </xsl:template>
    <xsl:template match="ota:RoomProfiles">
        <xsl:apply-templates select="ota:RoomProfile"/>
    </xsl:template>
    <xsl:template match="ota:RoomProfile">
        <Product>
            <!--xsl:value-of select="@BookingCode"/-->
            <!--         <xsl:value-of select="substring(@BookingCode,4)"/>-->
            <xsl:choose>
                <xsl:when test="$request_rootNode = 'OTA_TT_PkgBookRQ'">
                    <xsl:value-of select="substring(@BookingCode,4)"/>
                </xsl:when>
                <xsl:when test="$request_rootNode = 'OTA_TT_PkgQuoteRQ' and $packageNode = ''">
                    <!-- hotel only -->
                    <xsl:value-of select="substring(@BookingCode,5)"/>
                </xsl:when>
                <xsl:when test="$request_rootNode = 'OTA_TT_PkgQuoteRQ' and $packageNode != ''">
                    <xsl:value-of select="substring(@BookingCode,4)"/>
                </xsl:when>
            </xsl:choose>
        </Product>
        <Room>
            <xsl:value-of select="@RoomTypeCode"/>
        </Room>
    </xsl:template>
    <xsl:template match="ota:MealPlans">
        <xsl:apply-templates select="ota:MealPlan"/>
    </xsl:template>
    <xsl:template match="ota:MealPlan">
        <Meal>
            <xsl:value-of select="function:translateMealCode(@Code)"/>
        </Meal>
    </xsl:template>
    <xsl:template match="ota:PassengerListItems">
        <xsl:for-each select="ota:PassengerListItem">
            <xsl:sort select="@RPH"/>
            <xsl:apply-templates select="."/>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="ota:PassengerListItem">
        <Fap>
            <xsl:attribute name="ID"><xsl:value-of select="@RPH"/></xsl:attribute>
            <xsl:variable name="personencode">
                <xsl:value-of select="@Code"/>
            </xsl:variable>
            <xsl:variable name="personengender">
                <xsl:value-of select="@Gender"/>
            </xsl:variable>
            <PersonType>
                <xsl:choose>
                    <xsl:when test="@Code = '10' and @Gender ='Male'">M</xsl:when>
                    <xsl:when test="@Code = '10' and @Gender ='Female'">F</xsl:when>
                    <xsl:when test="@Age &lt;  2 ">I</xsl:when>
                    <xsl:when test="@Age &lt; 12 ">C</xsl:when>
                    <xsl:when test="@Age &lt; 2 ">I</xsl:when>
                    <xsl:when test="@Code = '8'">C</xsl:when>
                    <xsl:when test="@Code = '7'">I</xsl:when>
                    <xsl:when test="@BirthDate">
                        <xsl:variable name="age" select="function:getAge( @BirthDate, /*/*/ota:DateRange/@Start , 'yyyy-MM-dd')">
                    </xsl:variable>
                        <xsl:choose>
                            <xsl:when test="$age &lt; 2 ">4</xsl:when>
                            <xsl:when test="$age  &lt; 12 ">3</xsl:when>
                            <xsl:otherwise>M</xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise>M</xsl:otherwise>
                </xsl:choose>
            </PersonType>
            <!-- xsl:if test="ota:Name/ota:NamePrefix">
                <Title>
                    <xsl:value-of select="ota:Name/ota:NamePrefix/text()"/>
                </Title>
            </xsl:if-->
            <Name>
                <xsl:choose>
                    <xsl:when test="ota:Name/ota:Surname">
                        <xsl:choose>
                            <xsl:when test="string-length(ota:Name/ota:Surname/text()) &gt; 15">
                                <xsl:value-of select="substring(ota:Name/ota:Surname/text(),1,15)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="ota:Name/ota:Surname/text()"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise>Test</xsl:otherwise>
                </xsl:choose>
            </Name>
            <FirstName>
                <xsl:choose>
                    <xsl:when test="ota:Name/ota:GivenName">
                        <xsl:choose>
                            <xsl:when test="string-length(ota:Name/ota:GivenName/text()) &gt; 15">
                                <xsl:value-of select="substring(ota:Name/ota:GivenName/text(),1,15)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="ota:Name/ota:GivenName/text()"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:otherwise>Test</xsl:otherwise>
                </xsl:choose>
            </FirstName>
            <xsl:choose>
                <xsl:when test="@BirthDate">
                    <xsl:variable name="age" select="function:getAge( @BirthDate, /*/*/ota:DateRange/@Start , 'yyyy-MM-dd')"/>
                    <xsl:choose>
                        <xsl:when test="@Age &lt; 12 or @Age &lt; 2  or @Code = '8'  or @Code = '7' or $age &lt; 2 or $age  &lt; 12">
                            <Birth>
                                <xsl:value-of select="function:formatDate(@BirthDate, 'yyyy-MM-dd', 'ddMMyyyy')"/>
                            </Birth>
                        </xsl:when>
                    </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:if test="@Age">
                        <Age>
                            <xsl:value-of select="@Age"/>
                        </Age>
                    </xsl:if>
                </xsl:otherwise>
            </xsl:choose>
        </Fap>
    </xsl:template>
    <xsl:template name="PersonAssignment">
        <xsl:param name="allocation"/>
        <Persons>
            <xsl:call-template name="split">
                <xsl:with-param name="list" select="$allocation"/>
                <xsl:with-param name="delimiter" select="','"/>
                <xsl:with-param name="element" select="'IdRef'"/>
            </xsl:call-template>
        </Persons>
    </xsl:template>
    <xsl:template name="PersonsCounter">
        <xsl:param name="rphs"/>
        <xsl:param name="code"/>
        <xsl:param name="tag_name"/>
        <xsl:variable name="count" select="java:text.ParsePosition.new(0)"/>
        <xsl:for-each select="//ota:PassengerListItems/ota:PassengerListItem">
            <xsl:if test="$code = @Code and function:index-of($rphs, @RPH) > 0">
                <xsl:if test="java:setIndex($count, java:getIndex($count) + 1)"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:if test="java:getIndex($count) > 0">
            <xsl:element name="{$tag_name}">
                <xsl:value-of select="java:getIndex($count)"/>
            </xsl:element>
        </xsl:if>
    </xsl:template>
    <xsl:template name="buildFakeHotel">
        <Fah ServiceType="H">
            <xsl:attribute name="SegRef"><xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/><xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/></xsl:attribute>
            <xsl:choose>
                <!-- MLEFLOC/2012-03-19/2012-04-02 -->
                <xsl:when test="string-length(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/@DummyAccommodation) &gt; 28 ">
                    <xsl:variable name="newlist" select="concat(normalize-space(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/@DummyAccommodation), '/')"/>
                    <xsl:variable name="product" select="substring-before($newlist, '/')"/>
                    <xsl:variable name="remaining" select="substring-after($newlist, '/')"/>
                    <xsl:variable name="startDate" select="substring-before($remaining, '/')"/>
                    <xsl:variable name="remaining" select="substring-after($remaining, '/')"/>
                    <xsl:variable name="endDate" select="substring-before($remaining, '/')"/>
                    <StartDate>
                        <xsl:value-of select="datetime:format-date($startDate, 'ddMMyyyy')"/>
                    </StartDate>
                    <Duration>
                        <xsl:value-of select="function:getDuration($startDate, $endDate, 'yyyy-MM-dd')"/>
                    </Duration>
                    <Destination>
                        <xsl:value-of select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/ota:ArrivalAirport/@LocationCode"/>
                    </Destination>
                    <Product>
                        <xsl:value-of select="substring($product,4)"/>
                    </Product>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="ota:DateRange" mode="duration"/>
                    <Destination>
                        <xsl:value-of select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/ota:ArrivalAirport/@LocationCode"/>
                    </Destination>
                    <Product>
                        <xsl:value-of select="substring(ota:ItineraryItems/ota:ItineraryItem/ota:Flight/@DummyAccommodation,4)"/>
                    </Product>
                </xsl:otherwise>
            </xsl:choose>
            <Room>M11</Room>
            <!--Meal>OV</Meal-->
            <Persons>
                <xsl:value-of select="translate(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/ota:CabinAvailability/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
            </Persons>
        </Fah>
    </xsl:template>
</xsl:stylesheet>

It was going to help in terms of being able to run the xslt code itself on my machine, however its still looking for the common.xsl for import which is causing the error in compiling.

Trying to figure out how to point to the last one only, my initial thoughts would be to use a template to call two versions of your current template, one that selects the first instance, and the second, the last instance. However having issues matching the last instance using a variable set to the value of node count.

Need to find a way around that :/

I have done something like this, but it does not seems to work:

<xsl:choose>
    <xsl:when test="count(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']) > 1">
        <Fat ServiceType="T">
            <xsl:attribute name="SegRef">
                <xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/>
                <xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/>
            </xsl:attribute>
            <StartDate>
                <xsl:value-of select="datetime:format-date(substring(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/@DepartureDateTime, 1, 10), 'ddMMyyyy')"/>
            </StartDate>
            <Dep>
                <xsl:value-of select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/ota:DepartureAirport/@LocationCode"/>
            </Dep>
            <Arr>
                <xsl:value-of select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound' and last()]/ota:ArrivalAirport/@LocationCode"/>
            </Arr>
            <Persons>
                <xsl:value-of select="translate(//ota:CabinAvailability/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
            </Persons>
        </Fat>
    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']"/>
    </xsl:otherwise>
</xsl:choose>            

<xsl:choose>
    <xsl:when test="count(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']) > 1">
        <Fat ServiceType="T">
            <xsl:attribute name="SegRef">
                <xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/>
                <xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/>
            </xsl:attribute>
            <StartDate>
                <xsl:value-of select="datetime:format-date(substring(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']/@DepartureDateTime, 1, 10), 'ddMMyyyy')"/>
            </StartDate>
            <Dep>
                <xsl:value-of select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']/ota:DepartureAirport/@LocationCode"/>
            </Dep>
            <Arr>
                <xsl:value-of select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[last()][@DirectionInd='Inbound']/ota:ArrivalAirport/@LocationCode"/>
            </Arr>
            <Persons>
                <xsl:value-of select="translate(//ota:CabinAvailability/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
            </Persons>
        </Fat>

    </xsl:when>
    <xsl:otherwise>
        <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']"/>
    </xsl:otherwise>
</xsl:choose>            

The problem is that the last() function is not working somehow. I get the results for my inbound flight to be ZTH-CFU instead of ZTH-BRN.

Any help?

It'll probably be the 'and', have you tried '&' instead?

i have tried:

<xsl:variable name="arr" select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound' and last()]/ota:ArrivalAirport/@LocationCode"/>         

AND

<xsl:variable name="arr" select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound'][last()]/ota:ArrivalAirport/@LocationCode"/>            

but no affect.

& is not applicable.

Have to say im stumped now. I would recommend StackOverflow as a possible site for finding a solution, that is what I use myself.

I finally managed to resolve the problem.

<xsl:choose>
                    <xsl:when test="count(ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']) > 1">
                        <xsl:call-template name="prepareFatfromFlightSegment">
                            <xsl:with-param name="nodelist" select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Inbound']"/>
                    </xsl:otherwise>
                </xsl:choose>
                <xsl:apply-templates select="ota:ItineraryItems/ota:ItineraryItem/ota:Accommodation"/>
                <!-- xsl:apply-templates select="ota:Extras"/-->
                <!-- building fake hotel -->
                <xsl:if test="ota:ItineraryItems/ota:ItineraryItem/ota:Flight[@DirectionInd='Outbound']/@DummyAccommodation">
                    <xsl:call-template name="buildFakeHotel"/>
                </xsl:if>
                <xsl:call-template name="Insurance">
                    <xsl:with-param name="persons" select="//ota:PassengerRPHs/@ListOfPassengerRPH"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>


<xsl:template name="prepareFatfromFlightSegment">
        <xsl:param name="nodelist"/>
        <Fat ServiceType="T">
            <xsl:attribute name="SegRef"><xsl:if test="java:setIndex($rph_pos, java:getIndex($rph_pos) + 1)"/><xsl:value-of select="format-number(java:getIndex($rph_pos) - 1,'000.#')"/></xsl:attribute>
            <StartDate>
                <xsl:value-of select="datetime:format-date(substring($nodelist/@DepartureDateTime, 1, 10), 'ddMMyyyy')"/>
            </StartDate>
            <Dep>
                <xsl:value-of select="$nodelist/ota:DepartureAirport/@LocationCode"/>
            </Dep>
            <Arr>
                <xsl:value-of select="$nodelist[last()]/ota:ArrivalAirport/@LocationCode"/>
            </Arr>
            <Persons>
                <xsl:value-of select="translate(//ota:CabinAvailability/ota:PassengerRPHs/@ListOfPassengerRPH,' ', '')"/>
            </Persons>
        </Fat>
    </xsl:template>

Ah glad to see its fixed, sorry I wasnt of use :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.