1

For this XML -

<phoneContact>
    <firstName>XXXXX</firstName>
    <middleName>Y</middleName>
    <lastName>ZZZZZ</lastName>
    <generationalSuffix>Jr.</generationalSuffix>
    <phone>1234567890</phone>
</phoneContact>
<phoneContact>
    <firstName>AAAA</firstName>
    <middleName>B</middleName>
    <lastName>CCCCC</lastName>
    <phone>9876543210</phone>
    <!-- notice no generationalSuffix -->
</phoneContact>

and with this XSL -

<xsl:for-each select="phoneContact">
    <xsl:element name="phoneContact{position()}">
        <name>
            <xsl:if test="firstName">
                <xsl:value-of select="firstName"/>
                <xsl:text> </xsl:text> <!-- Add SPACE as a delimeter -->
            </xsl:if>
            <xsl:if test="middleName">
                <xsl:value-of select="middleName"/>
                <xsl:text> </xsl:text>
                </xsl:if>
            <xsl:if test="lastName">
                <xsl:value-of select="lastName"/>
                "<xsl:text> </xsl:text>
                </xsl:if>
            <xsl:if test="generationalSuffix">
                <xsl:value-of select="generationalSuffix"/>
                </xsl:if>
        </name>
        <phone><xsl:value-of select="phone"/></phone>
    </xsl:element>
</xsl:for-each>

I am using the XSL to -

  1. have Phone Contacts named as different elements "phoneContact1", "phoneContact2", and so forth
  2. get the name concatenated, with each name field separated by a SPACE.
  3. There should be no leading or trailing spaces in the "name".

This is giving me the desired output, except for not being able to handle a trailing space when an element's value is NULL.

<phoneContact1>
    <name>XXXXX Y ZZZZZ Jr.</name>
    <phone>1234567890</phone>
</phoneContact1>
<phoneContact2>
    <name>AAAA B CCCCC </name> <!-- notice the TRAILING space -->
    <phone>9876543210</phone>
</phoneContact2>

Any suggestions, please? Thank you.

1 Answer 1

3

An easy solution is using normalize-space on the concatenated values, this makes the stylesheet a lot more compacted:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/action">
    <xsl:for-each select="phoneContact">
      <xsl:element name="{concat('phoneContact',position())}">
        <name>
          <xsl:value-of select="normalize-space(concat(firstName,' ',middleName,' ',lastName,' ',generationalSuffix))" />
        </name>
        <phone><xsl:value-of select="phone"/></phone>
      </xsl:element>
    </xsl:for-each> 
  </xsl:template>
</xsl:stylesheet> 

Result:

<?xml version="1.0"?>
<phoneContact1>
    <name>XXXXX Y ZZZZZ Jr.</name><phone>1234567890</phone>
</phoneContact1>
<phoneContact2>
    <name>AAAA B CCCCC</name><phone>9876543210</phone>
</phoneContact2>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. This worked perfectly. I am an XSL noob, and will have to read up on normalize-space. Many thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.