2012-10-29 29 views
7

我有一個字符串,我需要每個單詞的第一個字母轉換爲大寫和休息使用XSL爲小寫,例如,轉換每個詞的第一個字符爲大寫

輸入字符串= DINESH sAchdeV卡皮木

所需的輸出字符串=迪內希Sachdev卡皮木

雖然,我知道我必須使用爲目的翻譯的功能,但我怎麼能翻譯每一個字大寫的第一個章程,其餘全部在小寫使用XSLT 1.0

感謝

回答

10

以下是不是「好」,我敢肯定有人(主要是迪米特里)能拿出一些更簡單(特別是在XSLT 2.0)...但我已經tested this and it works

<xsl:template name="CamelCase"> 
    <xsl:param name="text"/> 
    <xsl:choose> 
    <xsl:when test="contains($text,' ')"> 
     <xsl:call-template name="CamelCaseWord"> 
     <xsl:with-param name="text" select="substring-before($text,' ')"/> 
     </xsl:call-template> 
     <xsl:text> </xsl:text> 
     <xsl:call-template name="CamelCase"> 
     <xsl:with-param name="text" select="substring-after($text,' ')"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:call-template name="CamelCaseWord"> 
     <xsl:with-param name="text" select="$text"/> 
     </xsl:call-template> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="CamelCaseWord"> 
    <xsl:param name="text"/> 
    <xsl:value-of select="translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" /><xsl:value-of select="translate(substring($text,2,string-length($text)-1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')" /> 
</xsl:template> 

基本思路是你撥打CamelCase,如果找到空格,那麼它在之前運行CamelCaseWord之前的空格(即第一個單詞),然後在之後(即句子的其餘部分)再次撥打CamelCase之間的所有內容。否則,如果沒有找到空格(因爲它到了句子中的最後一個單詞),那麼它只會調用CamelCaseWord

CamelCaseWord模板只是將第一個字符從低位轉換爲高位(如有必要),並將所有剩餘字符從高位轉換爲低位(如有必要)。

所以調用它,你就會有...

<xsl:call-template name="CamelCase"> 
    <xsl:with-param name="text">dInEsh sAchdeV kApil Muk</xsl:with-param> 
</xsl:call-template> 
3

附加:

我錯過了問題1.0的要求。這隻適用於2.0版本。

這裏下面的原始答案。

我相信這個人不久前爲我工作。聲明函數:

<xsl:function name="my:titleCase" as="xs:string"> 
    <xsl:param name="s" as="xs:string"/> 
    <xsl:choose> 
     <xsl:when test="lower-case($s)=('and','or')"> 
      <xsl:value-of select="lower-case($s)"/> 
     </xsl:when> 
     <xsl:when test="$s=upper-case($s)"> 
      <xsl:value-of select="$s"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="concat(upper-case(substring($s, 1, 1)), lower-case(substring($s, 2)))"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:function> 

並使用它:

<xsl:sequence select="string-join(for $x in tokenize($text,'\s') return my:titleCase($x),' ')"/> 

歸功於samjudson =>http://p2p.wrox.com/xslt/80938-title-case-string.html

+0

OP具有'XSLT的1.0'標籤...'低case'和'大寫'在1.0 – freefaller

+0

@freefaller Ooh中沒有,錯過了。 Wil改變了答案以反映這一點以備將來參考。謝謝! – Kris

3

這裏是一個8歲FXSL的1.x(的XSLT 1.0 libray完全寫在XSLT 1.0中)解決方案:

test-strSplit-to-Words 10.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
> 
    <xsl:import href="strSplitWordDel.xsl"/> 

    <!-- To be applied on: test-strSplit-to-Words10.xml --> 

    <xsl:output indent="yes" omit-xml-declaration="yes"/> 
    <xsl:variable name="vLower" 
     select="'abcdefgijklmnopqrstuvwxyz'"/> 
    <xsl:variable name="vUpper" 
     select="'ABCDEFGIJKLMNOPQRSTUVWXYZ'"/> 

    <xsl:template match="/"> 
     <xsl:variable name="vwordNodes"> 
     <xsl:call-template name="str-split-word-del"> 
      <xsl:with-param name="pStr" select="/"/> 
      <xsl:with-param name="pDelimiters" 
          select="', .(&#9;&#10;&#13;'"/> 
     </xsl:call-template> 
     </xsl:variable> 

     <xsl:apply-templates select="ext:node-set($vwordNodes)/*"/> 
    </xsl:template> 

    <xsl:template match="word"> 
     <xsl:choose> 
     <xsl:when test="not(position() = last())"> 
      <xsl:value-of 
      select="translate(substring(.,1,1),$vLower,$vUpper)"/> 
      <xsl:value-of select="substring(.,2)"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="."/> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="delim"> 
     <xsl:value-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

當這種轉化是在下面的XML文檔(測試strSplit到Words10施加。XML):

<t>004.lightning crashes (live).mp3</t> 

結果是

004.Lightning Crashes (Live).mp3 

當施加到這個XML文檔(你提供的樣品):

dInEsh sAchdeV kApil Muk 

結果是

DInEsh SAchdeV KApil Muk 

只需一點點tweek,我們得到這個代碼

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
> 
    <xsl:import href="strSplitWordDel.xsl"/> 

    <!-- To be applied on: test-strSplit-to-Words10.xml --> 

    <xsl:output indent="yes" omit-xml-declaration="yes"/> 
    <xsl:variable name="vLower" 
     select="'abcdefgijklmnopqrstuvwxyz'"/> 
    <xsl:variable name="vUpper" 
     select="'ABCDEFGIJKLMNOPQRSTUVWXYZ'"/> 

    <xsl:template match="/"> 
     <xsl:variable name="vwordNodes"> 
     <xsl:call-template name="str-split-word-del"> 
      <xsl:with-param name="pStr" select="/"/> 
      <xsl:with-param name="pDelimiters" 
          select="', .(&#9;&#10;&#13;'"/> 
     </xsl:call-template> 
     </xsl:variable> 

     <xsl:apply-templates select="ext:node-set($vwordNodes)/*"/> 
    </xsl:template> 

    <xsl:template match="word"> 
      <xsl:value-of 
      select="translate(substring(.,1,1),$vLower,$vUpper)"/> 
      <xsl:value-of select="translate(substring(.,2), $vUpper, $vLower)"/> 
    </xsl:template> 

    <xsl:template match="delim"> 
     <xsl:value-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

現在產生通緝的結果

Dinesh Sachdev Kapil Muk 

說明

str-split-word-delFXSL的模板可用於使用(可能多於一個)指定爲字符串參數的分隔符進行標記。

0

XQUERY上的這個函數:

函數Xquery爲Camel Case。

declare function xf:toCamelCase($text as xs:string?) as xs:string{ 
    if(contains($text,' ')) then 
     fn:concat(xf:CamelCaseWord(substring-before($text,' ')),' ', xf:toCamelCase(substring-after($text,' '))) 
    else 
     xf:CamelCaseWord($text) 
}; 

declare function xf:CamelCaseWord($text as xs:string?) as xs:string{ 
    fn:concat(translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 
       translate(substring($text,2,string-length($text)-1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')) 
}; 
0

一個非常簡短的解決方案,利用EXSLT的split()功能:

<xsl:variable name='text' select='"dInEsh sAchdeV kApil Muk"' /> 
<xsl:variable name='lowers' select='"abcdefghijklmnopqrstuvwxyz"' /> 
<xsl:variable name='uppers' select='"ABCDEFGHIJKLMNOPQRSTUVWXYZ"' /> 

<xsl:template match="/"> 

    <xsl:for-each select='str:split($text, " ")'> 
     <xsl:value-of select='concat(
      translate(substring(., 1, 1), $lowers, $uppers), 
      translate(substring(., 2), $uppers, $lowers), 
      " " 
     )' /> 
    </xsl:for-each> 
</xsl:template> 

工作演示:http://www.xmlplayground.com/CNmKdF

1

這裏還有一個簡短的解決方案。它使用純XSL-T 2.0。我知道OP已經爲XSL-T 1.0的要求,但由於該網頁的排名第一的谷歌的「XSL-T字母大寫功能」在2015年,這似乎更相關:

<xsl:function name="xx:fixCase"> 
    <xsl:param name="text" /> 
    <xsl:for-each select="tokenize($text,' ')"> 
     <xsl:value-of select="upper-case(substring(.,1,1))" /> 
     <xsl:value-of select="lower-case(substring(.,2))" /> 
     <xsl:if test="position() ne last()"> 
      <xsl:text> </xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:function> 

其中「XX」是你自己的名字空間。

2

你也可以試試這個:

http://www.xsltfunctions.com/xsl/functx_camel-case-to-words.html

<xsl:function name="functx:camel-case-to-words" as="xs:string" 
        xmlns:functx="http://www.functx.com"> 
     <xsl:param name="arg" as="xs:string?"/> 
     <xsl:param name="delim" as="xs:string"/> 

     <xsl:sequence select=" 
     concat(substring($arg,1,1), 
       replace(substring($arg,2),'(\p{Lu})', 
          concat($delim, '$1'))) 
    "/> 

</xsl:function> 

和向後: http://www.xsltfunctions.com/xsl/functx_words-to-camel-case.html

<xsl:function name="functx:words-to-camel-case" as="xs:string" 
       xmlns:functx="http://www.functx.com"> 
    <xsl:param name="arg" as="xs:string?"/> 

    <xsl:sequence select=" 
    string-join((tokenize($arg,'\s+')[1], 
     for $word in tokenize($arg,'\s+')[position() > 1] 
     return functx:capitalize-first($word)) 
     ,'') 
"/> 

</xsl:function> 
相關問題