3

xsl 2.0を使用して、すべての大文字のテキストを、各ノードの大文字のテキストの最初の文字のみを持つように変換しようとしています。それらは、多数の可能な子要素です。

<text> text text text
<head>BLAH <unkownTag>BLAH</unkownTag> BLAH </head>
</text>

これを次のように変換したい

<text> text text text
<head>Blah <unkownTag>Blah</unkownTag> Blah </head>
</text>

私が来た最も近いのは

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="head/text()">
    <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/>        
</xsl:template> 

それは私に結果を与えます

<text> text text text 
   <head>Blah <unkownTag>BLAH</unkownTag> blah </head>
</text>

頭のすべての子ノードで小文字の変換を実行するにはどうすればよいですか?

4

4 に答える 4

4

この変換により、単語を区切る句読点に関して、必要な結果が生成されます。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="head//text()">
  <xsl:analyze-string select="." regex="\p{{L}}+">
   <xsl:matching-substring>
     <xsl:value-of select=
      "concat(upper-case(substring(.,1,1)), lower-case(substring(.,2)))"/>
   </xsl:matching-substring>
   <xsl:non-matching-substring>
    <xsl:value-of select="."/>
   </xsl:non-matching-substring>
  </xsl:analyze-string>
 </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用する場合:

<text> text text text
 <head>BLAH <unkownTag>BLAH</unkownTag> BLAH </head>
</text>

必要な正しい結果が生成されます。

<text> text text text
 <head>Blah <unkownTag>Blah</unkownTag> Blah </head>
</text>

このXMLドキュメントに適用する場合:

<text> text text text
 <head>BLAH$<unkownTag>BLAH</unkownTag>-BLAH;</head>
</text>

ここでも正しい結果が生成されます。

<text> text text text
 <head>Blah$<unkownTag>Blah</unkownTag>-Blah;</head>
</text>

説明

  1. <xsl:analyze-string>命令の適切な使用。

  2. \p{L}文字クラスの適切な使用。

  3. <xsl:matching-substring>および<xsl:non-matching-substring>手順の適切な使用。

于 2013-02-27T03:24:59.570 に答える
1

あなたのテキストのスペースはこれを興味深い問題にしました。'head'の下のすべてのtext()ノードを照合するには、XPath式を使用して祖先を調べます。

ここでは、文字列をトークン化してから、結果セットをループして、最初の文字を大文字に変更し、次の文字を小文字に変更します。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="@*|node()">
       <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
       </xsl:copy>
   </xsl:template>

   <xsl:template match="text()[ ancestor::head ]">
       <xsl:value-of select="
            for $str in tokenize( ., '\s' ) 
            return concat( upper-case(substring($str,1,1)), 
                           lower-case(substring($str,2)) )"/>
   </xsl:template>
</xsl:stylesheet>
于 2013-02-27T02:15:38.887 に答える
0

これを試して。私はそれをテストしていません、そしてあなたはそれを少し微調整しなければならないかもしれません。

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="head">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()">
      <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>
于 2013-02-27T01:09:48.413 に答える
0

これは、途中で取得するのに役立つ場合があります。

<xsl:template match="/">
  <xsl:apply-templates select="node()" mode="firstup"/>
</xsl:template>

<xsl:template match="text()" mode="firstup">
  <!--<x>-->
    <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/>
  <!--</x>-->
</xsl:template>

3番目の「BLAH」についてはよくわかりませんが、このtext()ノードはスペースで始まるため、兄弟のテキストノードの大文字と小文字を正しく区別するのが難しくなります。これを確認するには、「x」要素のコメントを解除します。さらに詳しく知るために、スペースの正規化とposition()関数を確認することもできます。

于 2013-02-27T01:31:21.310 に答える