XSL: find matching Traveler by position in XML (since no unique identifier is found)

I have the following xsl and input file.
I want to populate Loyal/@givenName & Loyal/@surname by matching the TravelerID with the POSITION of where TravelerName exists.

Example:

TravelerIDs[@ID=T1]/Info/FFNumber  is linked to the 2nd Traveler in Request/TravelerName (i.e - JOHN DOE )
The way the TravelerName's are ordered is the same as the way the TravelerIds are odered



input file
<root>
	<Request>
		<TravelerName>
			<Surname>DOE</Surname>
			<GivenName>JANE</GivenName>
		</TravelerName>
		<TravelerName>
			<Surname>DOE</Surname>
			<GivenName>JOHN</GivenName>
		</TravelerName>
		<TravelerIDs ID="T2" Type="ADT"/>
		<TravelerIDs ID="T1" Type="ADT">
			<Info>
				<FFNumber>1234</FFNumber>
				<FFCompanyCode>RT</FFCompanyCode>
			</Info>
		</TravelerIDs>
	</Request>
</root>

Open in new window




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

  <xsl:template match="/root">
    <Request>
      <xsl:for-each select="Request/TravelerIDs">
        <Qualifiers>
          <xsl:attribute name="Type">
            <xsl:value-of select="@Type"/>
          </xsl:attribute>
          <Traveler>
            <xsl:value-of select="translate ( @ID, 'T', '')"/>
          </Traveler>
          <xsl:if test="Info">
            <Loyal>
              <xsl:attribute name="code">
                <xsl:value-of select="Info/FFCompanyCode"/>
              </xsl:attribute>
              <xsl:attribute name="givenName">
                <xsl:value-of select="../Traveler/TravelerName/GivenName"/>
              </xsl:attribute>
              <xsl:attribute name="surname">
                <xsl:value-of select="../Traveler/TravelerName/Surname"/>
              </xsl:attribute>
              <xsl:value-of select="FQTVInfo/FFNumber"/>
            </Loyal>
          </xsl:if>
        </Qualifiers>
      </xsl:for-each>
    </Request>
  </xsl:template>
</xsl:stylesheet>

Open in new window

badtz7229Asked:
Who is Participating?
 
Geert BormansInformation ArchitectCommented:
Try this for positional reference

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" encoding="UTF-8"/>
    
    <xsl:template match="/root">
        <Request>
            <xsl:for-each select="Request/TravelerIDs">
                <xsl:variable name="position" select="position() - 1"></xsl:variable>
                <Qualifiers>
                    <xsl:attribute name="Type">
                        <xsl:value-of select="@Type"/>
                    </xsl:attribute>
                    <Traveler>
                        <xsl:value-of select="translate ( @ID, 'T', '')"/>
                    </Traveler>
                    <xsl:if test="Info">
                        <Loyal>
                            <xsl:attribute name="code">
                                <xsl:value-of select="Info/FFCompanyCode"/>
                            </xsl:attribute>
                            <xsl:attribute name="givenName">
                                <xsl:value-of select="../TravelerName[count(preceding-sibling::TravelerName) = $position]/GivenName"/>
                            </xsl:attribute>
                            <xsl:attribute name="surname">
                                <xsl:value-of select="../TravelerName[count(preceding-sibling::TravelerName) = $position]/Surname"/>
                            </xsl:attribute>
                            <xsl:value-of select="FQTVInfo/FFNumber"/>
                        </Loyal>
                    </xsl:if>
                </Qualifiers>
            </xsl:for-each>
        </Request>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
badtz7229Author Commented:
that worked

can you please explain how you are doing this?
0
 
Geert BormansInformation ArchitectCommented:
this variable
                <xsl:variable name="position" select="position() - 1"></xsl:variable>
counts the number of TravelerIDs before the current TravelerIDs

I then use that variable in this expression
../TravelerName[count(preceding-sibling::TravelerName) = $position]
is the TravelerName that has a number of preceding sibling TravelerName elements equal to $position
in other words: it returns the TravelerName at the exact relative position as the TravelerIds we are currently processing
0
 
badtz7229Author Commented:
Thank u
0
 
Geert BormansInformation ArchitectCommented:
welcome
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.