12

String があり、xsl を使用して各単語の最初の文字を大文字に変換し、残りを小文字に変換する必要があります。たとえば、

入力文字列 = dInEsh sAchdeV kApil Muk

望ましい出力文字列 = Dinesh Sachdev Kapil Muk

ただし、目的のために翻訳機能を使用する必要があることはわかっていますが、XSLT 1.0 を使用して、各単語の最初のチャーターを大文字に変換し、残りをすべて小文字にするにはどうすればよいですか?

ありがとう

4

8 に答える 8

18

以下は「良い」ものではなく、誰か (主にディミトリ) がもっと単純なもの (特に 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のすべて(つまり最初の単語)で実行され、スペースののすべて(つまり文の残り) で再度呼び出されるというものです。それ以外の場合、スペースが見つからない場合 (文の最後の単語に達したため)、単に を呼び出します。CamelCaseCamelCaseWord

テンプレートはCamelCaseWord、最初の文字を小文字から大文字に変換し (必要な場合)、残りのすべての文字を大文字から小文字に変換します (必要な場合)。

つまり、それを呼び出すには...

<xsl:call-template name="CamelCase">
   <xsl:with-param name="text">dInEsh sAchdeV kApil Muk</xsl:with-param>
</xsl:call-template>
于 2012-10-29T13:53:59.040 に答える
5

追加:

質問の 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

于 2012-10-29T14:18:14.797 に答える
4

以下は、8 年前の FXSL 1.x (XSLT 1.0 で完全に記述された XSLT 1.0 ライブラリ) ソリューションです。

test-strSplit-to-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="', .(&#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 ドキュメント (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="', .(&#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

説明:

FXSLstr-split-word-delテンプレートは、文字列パラメーターとして指定された (場合によっては複数の) 区切り文字によるトークン化に使用できます。

于 2012-10-29T22:52:58.050 に答える
0

XQUERY でのこの同じ関数:

関数 Xquery to 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'))
};
于 2013-10-17T19:05:38.230 に答える
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

于 2014-02-04T13:30:55.527 に答える