我有一个字符串,我需要将每个单词的第一个字母转换为上案例,然后使用XSL将其休息为较低的情况,例如,
输入字符串= Dinesh Sachdev Kapil Muk
所需的输出字符串= Dinesh Sachdev Kapil Muk
,尽管我知道我必须将翻译功能用于此目的,但是我如何将每个单词的第一个章程转换为上案例,并使用XSLT 1.0
在下情况下全部休息谢谢
以下不是"好",我敢肯定有人(主要是dimitri)可能会提出更简单的内容(尤其是在XSLT 2.0中)...但是我已经测试过这和它有效
<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-case-string.html
这是一个8年的FXSL 1.x(XSLT 1.0库完全写在XSLT 1.0中)解决方案:
test-strsplit-words10.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文档(test-strsplit-to-words10.xml)上应用此转换时:
<t>004.lightning crashes (live).mp3</t>
结果是:
004.Lightning Crashes (Live).mp3
应用于此XML文档(您提供的样本):
dInEsh sAchdeV kApil Muk
结果是:
DInEsh SAchdeV KApil Muk
只有一个小点,我们得到此代码:
<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
说明:
fxsl 的str-split-word-del
模板可用于以(可能多个)定义为字符串参数的特定器。
这是另一个简短解决方案。它使用纯XSL-T 2.0。我知道OP对XSL-T 1.0有要求,但是由于此页面在2015年的" XSL-T标题案例功能"上排名第一,因此这似乎更相关:
<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-case-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>
xquery上的同一功能:
功能xquery到骆驼盒。
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>
工作演示:http://www.xmlplayground.com/cnmkdf
可以使用单线表达式来实现。尝试此
string-join(for $x in tokenize($text,'s') return concat(upper-case(substring($x, 1, 1)), lower-case(substring($x, 2))),' ')
注意 - 已通过Orbeon表单公式进行了验证。
我最终得到了一些不同的东西。使用我得到的另一个答案:
由于a的结果,不允许多个项目的序列致电toddmo:适当案例#1("嘿"
这样可以解决。
<xsl:stylesheet xmlns:toddmo="https://todd.mo"
<xsl:function name="toddmo:proper-case" as="xs:string">
<xsl:param name="text" />
<xsl:variable name="words">
<xsl:for-each select="tokenize($text,' ')">
<xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/>
<xsl:if test="position()!=last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($words,'')"/>
</xsl:function>
测试
<xsl:value-of select="toddmo:proper-case('hI my name is toddmo')"/>
输出
嗨,我叫toddmo