我有一個字符串,我需要每個單詞的第一個字母轉換爲大寫和休息使用XSL爲小寫,例如,轉換每個詞的第一個字符爲大寫
輸入字符串= DINESH sAchdeV卡皮木
所需的輸出字符串=迪內希Sachdev卡皮木
雖然,我知道我必須使用爲目的翻譯的功能,但我怎麼能翻譯每一個字大寫的第一個章程,其餘全部在小寫使用XSLT 1.0
感謝
我有一個字符串,我需要每個單詞的第一個字母轉換爲大寫和休息使用XSL爲小寫,例如,轉換每個詞的第一個字符爲大寫
輸入字符串= DINESH sAchdeV卡皮木
所需的輸出字符串=迪內希Sachdev卡皮木
雖然,我知道我必須使用爲目的翻譯的功能,但我怎麼能翻譯每一個字大寫的第一個章程,其餘全部在小寫使用XSLT 1.0
感謝
以下是不是「好」,我敢肯定有人(主要是迪米特里)能拿出一些更簡單(特別是在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>
附加:
我錯過了問題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
這裏是一個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="', .(	 '"/>
</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="', .(	 '"/>
</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-del
FXSL的模板可用於使用(可能多於一個)指定爲字符串參數的分隔符進行標記。
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'))
};
一個非常簡短的解決方案,利用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>
這裏還有一個簡短的解決方案。它使用純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」是你自己的名字空間。
你也可以試試這個:
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>
OP具有'XSLT的1.0'標籤...'低case'和'大寫'在1.0 – freefaller
@freefaller Ooh中沒有,錯過了。 Wil改變了答案以反映這一點以備將來參考。謝謝! – Kris