NCollinsTE
NCollinsTE

Reputation: 309

XSL Display first letter of Node after a Space (If a space exists)

I have a node in my XML for First Name which includes the middle initial IF the middle initial exists. (the database that feeds the XML does not have a Middle Initial field).

Examples:

<billing-firstname>Nicholas M.</billing-firstname>
<billing-firstname>Timothy</billing-firstname>

I want to be able to display this as just the initials.

Output Examples:

N. M.
T. 

I already know how to snag the first character of the node, just not how to split it up w/ First Initial then Middle initial IF it exists.

<xsl:value-of select="substring(billing-firstname,1,1)" />

Any assistance would be greatly appreciated.

-Nick

Upvotes: 1

Views: 358

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

This XSLT 2.0 transformation:

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

  <xsl:template match="billing-firstname">
    <xsl:for-each select="tokenize(., ' ')">
      <xsl:value-of select="concat(substring(.,1,1), '. ')"/>
    </xsl:for-each>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

When applied on the provided XML (wrapped in a single top element to make it well-formed XML document):

<t>
    <billing-firstname>Nicholas M.</billing-firstname>
    <billing-firstname>Timothy</billing-firstname>
</t>

produces the wanted, correct result:

N. M. 
T. 

Upvotes: 1

Daniel Haley
Daniel Haley

Reputation: 52878

Since you're using XSLT 2.0 (with XPath 2.0), you could use a combination of for, tokenize, substring, concat, and string-join...

string-join(for $name in tokenize(normalize-space(),'\s') return concat(substring($name,1,1),'.'),' ')

Example:

XML Input

<doc>
    <billing-firstname>Nicholas M.</billing-firstname>
    <billing-firstname>Timothy</billing-firstname>
</doc>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="billing-firstname">
    <xsl:copy>
      <xsl:value-of select="string-join(for $name in tokenize(normalize-space(),'\s') return concat(substring($name,1,1),'.'),' ')"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

XML Output

<doc>
   <billing-firstname>N. M.</billing-firstname>
   <billing-firstname>T.</billing-firstname>
</doc>

Upvotes: 1

Related Questions