Link to home
Start Free TrialLog in
Avatar of tesmc
tesmcFlag for United States of America

asked on

How to count @Type given xml input

I want to count the amount of unique Traveler/@Type given the below xml input

I'm iterating through Ticket/TravelerRQ to get all my TktTraveler  but then I want to match it to View/Traveler/ElementNumber and group by Traveler/@Type to see how many of that type I have.



<root>
	<Ticket>
		<TravelerRQ>
			<TktTraveler Element="1"/>
			<TktTraveler Element="2"/>
		</TravelerRQ>
		<View>
			<Traveler Type="ADT">
				<ElementNumber>1</ElementNumber>
				<TravelerName>
					<LastName>DOE</LastName>
					<FirstName>JOHN</FirstName>
				</TravelerName>
			</Traveler>
			<Traveler Type="ADT">
				<ElementNumber>2</ElementNumber>
				<TravelerName>
					<LastName>DOE</LastName>
					<FirstName>JANE</FirstName>
				</TravelerName>
			</Traveler>
		</View>
	</Ticket>
</root>

Open in new window


Expected response = 2 ADT
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

<xsl:value-of select="count(distinct-values(//Traveler/@Type))"/>
mmh, thought you needed the total

        <xsl:for-each-group select="//Traveler" group-by="@Type">
            <xsl:value-of select="count(current-group())"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="current-grouping-key()"/>
            <xsl:text>; </xsl:text>
        </xsl:for-each-group>

Open in new window

Avatar of tesmc

ASKER

@Geert Bormans - Im using version 1.0 so that function distinct-values is not recognized.
for-each group won't be either  then
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tesmc

ASKER

thank you for your help.
Avatar of tesmc

ASKER

I have follow-up question. The above solution is such that it does a count on Ticket/View/Traveler but what if I had an input as:

      

<root>
	<Ticket>
		<TravelerRQ>
			<TktTraveler Element="1"/>
		</TravelerRQ>
		<View>
			<Traveler Type="ADT">
				<ElementNumber>1</ElementNumber>
				<TravelerName>
					<LastName>DOE</LastName>
					<FirstName>JOHN</FirstName>
				</TravelerName>
			</Traveler>
			<Traveler Type="ADT">
				<ElementNumber>2</ElementNumber>
				<TravelerName>
					<LastName>DOE</LastName>
					<FirstName>JANE</FirstName>
				</TravelerName>
			</Traveler>
		</View>
	</Ticket>
</root>

Open in new window


then i would expect result = 1 ADT because I'm wanting count of Travelers that are found in Ticket/TravelerRQ grouped by the @Type found in Ticket/View/Traveler/ElementNumber
I would guess

Add a second key and a condition

The condition [key('tkt', ElementNumber)] says the nodeset found by doing an index lookup based on the ElementNumber is not empty

    <xsl:key name="type" match="Traveler" use="@Type"/>
    <xsl:key name="tkt" match="TktTraveler" use="@Element"/>
    
    <xsl:template match="root">
        <xsl:for-each select="//Traveler[generate-id() = generate-id(key('type', @Type)[key('tkt', ElementNumber)][1])]">
            <xsl:value-of select="count(key('type', @Type)[key('tkt', ElementNumber)])"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="@Type"/>
            <xsl:text>; </xsl:text>
        </xsl:for-each>
    </xsl:template>
    

Open in new window

Avatar of tesmc

ASKER

@Gertone (Geert Bormans) - thanks that worked to for me.