2013-02-13 49 views
1

我需要从以下字符串拉出的最后一个字的使用姓氏:XSLT 1.0版本需要拔出串的最后一个字

<CUSTOMER_x0020_NAME>Mr Tim Cookson</CUSTOMER_x0020_NAME> 

所以我只需要拉出“库克森'使用XSLT,我该怎么做?尝试了几次关系后,但没有运气。

回答

0

您可以使用此递归模板得到一个值的最后一个字:

<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> 
+0

谢谢,这伟大工程。举个例子,如果我刚刚拿出蒂姆库克森先生的'蒂姆',那怎么样? – user2069189 2013-02-14 10:09:10

+0

这种情况下选择“Tim”的标准是什么?第一个空格之后的第一个单词? – JLRishe 2013-02-14 10:15:49

2

这是一个非递归解决方案,它与任何非字母字符(但最后一个单词后的字符,如果有的话,应该只有空格)的字分隔符一起工作:

<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 
+1

非常好。迪米特雷,你的狡猾和聪明才智永远不会激励我。 (那些喜欢我的人试图更好地理解这个解决方案中的黑魔法是如何工作的,可能会发现自问自己将最后一个符号开始超过82个字符的字符串发生到字符串的空间规范化形式中会发生什么,并且问自己为什么会发生这种情况,以及如何使它成为82以外的数字。) – 2013-02-14 17:36:14

+0

@ CMSperberg-McQueen,这个问题的答案在我写于10年前的一篇文章中:'' - 这包含足够的节点来开始:) – 2013-02-14 19:11:09