I do not want to display a comma after last element

Here should go questions about transforming XML with XSLT and FOP.
winkimjr2
Posts: 53

I do not want to display a comma after last element

Fri Feb 27, 2015 9:59 pm

In my schema I have AddressLine1, AddressLine2, AddressLine3 and AddressLine4. When address is added to each AddressLine a comma is inserted to separate the AddressLines. However if only AddressLine1 and AddressLine2 have address, then there should not be a comma after the AddressLine2 because there is nothing else after it.
My output is showing a trailing comma after AddressLine2 even though it should not.
Output
472 Case Ave, Apt 2, Saint Paul, MN, 55106; 123 Beautiful Ocean, Sydney Australia 123456A,
Xml Code

Code: Select all

<ProtectedAddresses>
   <Address InternalAddressID="1618212013" Type="Non Standard">
      <Location Word="HOME">Home</Location>
      <AddressLine1>472 Case Ave</AddressLine1>
      <AddressLine2>Apt 2</AddressLine2>
      <AddressLine4>Saint Paul, MN, 55106</AddressLine4>
      <City>Saint Paul</City>
      <State>MN</State>
      <Zip>55106</Zip>
   </Address>
   <Address InternalAddressID="1618212014" Type="Foreign">
      <Location Word="OTHER">Other</Location>
      <AddressLine1>123 Beautiful Ocean</AddressLine1>
      <AddressLine2>Sydney Australia 123456A</AddressLine2>
      <Foreign>true</Foreign>
   </Address>
</ProtectedAddresses>


Xslt code

Code: Select all

<xsl:for-each select="Addresses/Address">
   <xsl:for-each select="Address[@InternalAddressID=current()/@InternalAddressID]">
      <xsl:if test="AddressLine1">
   <xsl:value-of select="AddressLine1"/>
   <xsl:text>, </xsl:text>
      </xsl:if>
      <xsl:if test="AddressLine2">
   <xsl:value-of select="AddressLine2"/>
   <xsl:text>, </xsl:text>
   </xsl:if>
      <xsl:if test="AddressLine3">
   <xsl:value-of select="AddressLine3"/>
   <xsl:text>, </xsl:text>
      </xsl:if>
      <xsl:if test="AddressLine4">
   <xsl:value-of select="AddressLine4"/>
      </xsl:if>
   <xsl:text>; </xsl:text>
   </xsl:for-each>
</xsl:for-each>
lief.erickson
Posts: 14

Re: I do not want to display a comma after last element

Mon Mar 02, 2015 1:26 am

The reason you're getting the extra comma is because of:

Code: Select all

<xsl:if test="AddressLine2">
   <xsl:value-of select="AddressLine2"/>
   <xsl:text>, </xsl:text>
</xsl:if>


This says: For every AddressLine2, emit its value and then follow that with a comma and then a space. Repeat for each and every AddressLine2. But that's not what you want.

Instead, you want to have an if/then happen. In XSLT, if/then is done with <xsl:choose>. A <xsl:choose> will give you control when to emit the comma & space. You can do this by checking the following-sibling. If the following-sibling is 'Foreign' then do not emit the comma & space. If it's anything else (e.g., AddressLine4, City, State, ScoobySnacks, etc.), it will emit the comma & space.

What I've provided below works for me, but is far from ideal. (I'm still fairly new to XSLT.) You may have to modify it for your own environment (especially the for-each select="Address" to add your attributes).

Code: Select all

    <xsl:template match="ProtectedAddresses">
        <xsl:for-each select="Address">
            <xsl:for-each select="AddressLine1">
                <xsl:value-of select="."/>
                <xsl:text>, </xsl:text>
            </xsl:for-each>
            <xsl:for-each select="AddressLine2">
                <xsl:value-of select="."/>
                <xsl:choose>
                    <xsl:when test="following-sibling::Foreign">
                        <!-- Do nothing -->
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:text>, </xsl:text>
                    </xsl:otherwise>
                </xsl:choose>
               
            </xsl:for-each>
            <xsl:for-each select="AddressLine4">
                <xsl:value-of select="."/>
            </xsl:for-each>
            <xsl:text>; </xsl:text> 
        </xsl:for-each>

    </xsl:template>
Patrik
Posts: 228
Location: Hamburg/Germany

Re: I do not want to display a comma after last element

Mon Mar 02, 2015 9:19 am

Hi,

this could be done with string-join:
<xsl:value-of select="string-join((AddressLine1, AddressLine2, AddressLine3, AddressLine4), ', ')"/>

It first create a list of all (existing) AddressLine*-elements and string-join will just add a ", " between all elements.

regards,

Patrik
winkimjr2
Posts: 53

Re: I do not want to display a comma after last element

Mon Mar 02, 2015 5:40 pm

Thanks to both lief.erickson and Patrik. I adopted lief.erickson solution and my problem has been solved!
winkimjr2
Posts: 53

Re: I do not want to display a comma after last element

Mon Mar 02, 2015 7:27 pm

Patrik, when I used this

Code: Select all

<xsl:value-of select="string-join((AddressLine1, AddressLine2, AddressLine3, AddressLine4), ', ')"/>
line of code in my xslt, I received this error:

XSL transformation failed due to following error: Expected token ')' found ','.
How do I resolve this?
Patrik
Posts: 228
Location: Hamburg/Germany

Re: I do not want to display a comma after last element

Tue Mar 03, 2015 8:04 am

This code

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   exclude-result-prefixes="xs"
   version="2.0">
   
   <xsl:template match="Address">
      <xsl:value-of select="string-join((AddressLine1, AddressLine2, AddressLine3, AddressLine4), ', ')"/>
   </xsl:template>
   
</xsl:stylesheet>


works fine with saxon EE, PE and HE. What xslt engine are you using?

Return to “XSLT and FOP”

Who is online

Users browsing this forum: No registered users and 0 guests