XSLT - How to check for last element

I need a method of checking for the last element in an xml document. For example, here you can see I have three elements of type "PersonConsentGiver." I need an XSL method to check to see if it is the last PersonConsentGiver in the list to make sure that I don't put a comma at the end of the last persons name. My XSLT that I am using is written below the XML :

 <PersonConsentGiver>
    <FirstName>First</FirstName>
    <LastName>Last</LastName>
 </PersonConsentGiver>
 <PersonConsentGiver>
    <FirstName>First</FirstName>
    <LastName>Last</LastName>
 </PersonConsentGiver>
<PersonConsentGiver>
    <FirstName>First</FirstName>
    <LastName>Last</LastName>
 </PersonConsentGiver>
 

<xsl:template match="Document/PersonConsentGiver" mode="ConsentGivers">
<xsl:value-of select="FirstName"/> <xsl:text> (</xsl:text><xsl:value-of select="LastName"/> <xsl:text>), </xsl:text>
</xsl:template>
dwmickschAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Gertone (Geert Bormans)Information ArchitectCommented:
Hi dwmicksch,

you could use functions like position() and last()
but the way your template is currently set up, those functions would count the whitespace text nodes as well

if you just pass the used nodeset to the PersonConsentGiver template
it would not count the white-space nodes, and you would have correct counts
you can do that with a selective apply-templates

here is an example
(I add newlines because you loose them in the selective apply-templates)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:param name="newline"><xsl:text>
</xsl:text></xsl:param>
    <xsl:template match="Document">
        <xsl:apply-templates select="PersonConsentGiver"/>
    </xsl:template>
    <xsl:template match="PersonConsentGiver">
        <xsl:value-of select="FirstName"/> <xsl:text> (</xsl:text><xsl:value-of select="LastName"/> <xsl:text>)</xsl:text>
        <xsl:if test="not(position() = last())"><xsl:text>,</xsl:text></xsl:if>
        <xsl:value-of select="$newline"/>
     </xsl:template>
</xsl:stylesheet>

you see, if you pass the correct nodeset, it is just a simple test to add the comma


Cheers!

Gertone
Gertone (Geert Bormans)Information ArchitectCommented:
dwmicksch,

there is a less intrusive solution,
that checks the following-sibling path

    <xsl:template match="Document/PersonConsentGiver">
        <xsl:value-of select="FirstName"/> <xsl:text> (</xsl:text><xsl:value-of select="LastName"/> <xsl:text>)</xsl:text>
        <xsl:if test="following-sibling::PersonConsentGiver"><xsl:text>,</xsl:text></xsl:if>
     </xsl:template>

I think you now have the two options that are used the most

cheers

Geert

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.