姓を使用するには、次の文字列から最後の単語を取り出す必要があります。
<CUSTOMER_x0020_NAME>Mr Tim Cookson</CUSTOMER_x0020_NAME>
では、XSLT を使用して 'Cookson' を引き出す必要があるだけですが、これを行うにはどうすればよいでしょうか? substring-after との関係をいくつか試しましたが、うまくいきませんでした。
これは、アルファベット以外の文字である単語区切り文字で機能する非再帰的なソリューションです(ただし、最後の単語の後の文字は、もしあればスペースのみにする必要があります)。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pLower" select=
"'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:param name="pUpper" select=
"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="vAlpha" select="concat($pUpper, $pLower)"/>
<xsl:template match="text()">
<xsl:variable name="vText" select="normalize-space()"/>
<xsl:variable name="vLength" select="string-length($vText)"/>
<xsl:variable name="vPunct" select="translate(., $vAlpha, '')"/>
<xsl:for-each select=
"document('')//node()
|document('')//@*
|document('')//namespace::*">
<xsl:variable name="vPos" select="position()"/>
<xsl:variable name="vRemaining"
select="substring($vText, $vPos)"/>
<xsl:if test=
"contains($vPunct, substring($vRemaining,1,1))
and
$vLength -$vPos
= string-length(translate($vRemaining, $vPunct, ''))
">
<xsl:value-of select="substring($vRemaining,2)"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用されると、次のようになります。
<CUSTOMER_x0020_NAME>Mr Tim Cookson</CUSTOMER_x0020_NAME>
必要な正しい結果が生成されます。
Cookson
この XML ドキュメントに同じ変換を適用すると、次のようになります。
<CUSTOMER_x0020_NAME>Mr. Tim Berners-Lee</CUSTOMER_x0020_NAME>
ここでも正しい結果が生成されます。
Lee
この再帰テンプレートを使用して、値の最後の単語を取得できます。
<xsl:template name="GetLastWord">
<xsl:param name="value" />
<xsl:variable name="normalized" select="normalize-space($value)" />
<xsl:choose>
<xsl:when test="contains($normalized, ' ')">
<xsl:call-template name="GetLastWord">
<xsl:with-param name="value" select="substring-after($normalized, ' ')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$normalized"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
このテンプレートを XSLT に追加し、次のように呼び出すだけです。
<xsl:call-template name="GetLastWord">
<xsl:with-param name="value" select="CUSTOMER_x0020_NAME" />
</xsl:call-template>