質問

小文字と大文字の境界でタグを分割することは可能ですか? たとえば、タグ「UserLicenseCode」は「User License Code」に変換する必要があります 列ヘッダーが少し見栄えがよくなります。

過去にPerlの正規表現を使用してこのようなことをしましたが、 XSLTは私にとってまったく新しいボールゲームです。

このようなテンプレートを作成するためのポインタは大歓迎です!

ありがとう クリシュナ

役に立ちましたか?

解決

再帰を使用すると、XSLTの文字列をウォークスルーしてすべての文字を評価できます。これを行うには、1つの文字列パラメーターのみを受け入れる新しいテンプレートを作成します。最初の文字を確認し、大文字の場合はスペースを書きます。次に、文字を書きます。次に、単一の文字列内に残りの文字を指定して、テンプレートを再度呼び出します。これはあなたがしたいことになるでしょう。

それがあなたのポインタです。テンプレートを作成するには時間がかかります。 :-)


特に全体のスペースを確保するには、いくつかのテストが必要でした。 (私はこのためにキャラクターを誤用しました!)しかし、このコードはあなたにアイデアを与えるはずです...

このXMLを使用しました:

<?xml version="1.0" encoding="UTF-8"?>
<blah>UserLicenseCode</blah>

そしてこのスタイルシート:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="text"/>
    <xsl:variable name="Space">*</xsl:variable>
    <xsl:template match="blah">
    <xsl:variable name="Split">
        <xsl:call-template name="Split">
            <xsl:with-param name="Value" select="."/>
            <xsl:with-param name="First" select="true()"/>
        </xsl:call-template></xsl:variable>
        <xsl:value-of select="translate($Split, '*', ' ')" />
    </xsl:template>
    <xsl:template name="Split">
        <xsl:param name="Value"/>
        <xsl:param name="First" select="false()"/>
        <xsl:if test="$Value!=''">
            <xsl:variable name="FirstChar" select="substring($Value, 1, 1)"/>
            <xsl:variable name="Rest" select="substring-after($Value, $FirstChar)"/>
                <xsl:if test="not($First)">
                    <xsl:if test="translate($FirstChar, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '..........................')= '.'">
                        <xsl:value-of select="$Space"/>
                    </xsl:if>
                </xsl:if>
                <xsl:value-of select="$FirstChar"/>
                <xsl:call-template name="Split">
                    <xsl:with-param name="Value" select="$Rest"/>
                </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

そして結果としてこれを得た:

User License Code

スペースやその他の空白文字はXMLから削除される傾向があることに留意してください。そのため、代わりにスペースに変換した「*」を使用しました。

もちろん、このコードは改善できます。それは私が10分の仕事で思いつくことができたものです。他の言語では、コードの行数は少なくなりますが、XSLTでは、含まれるコード行の量を考慮すると、依然として非常に高速です。

他のヒント

XSLT + FXSLソリューション(XSLT 2.0で、ただしほぼ同じコードがXSLT 1.0とFXSL 1.xで機能します

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:testmap="testmap"
exclude-result-prefixes="f testmap"
>
   <xsl:import href="../f/func-str-dvc-map.xsl"/>
   <testmap:testmap/>

   <xsl:output omit-xml-declaration="yes" indent="yes"/>

   <xsl:template match="/">
     <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>

     '<xsl:value-of select="f:str-map($vTestMap, 'UserLicenseCode')"
       />'
   </xsl:template>

    <xsl:template name="mySplit" match="*[namespace-uri() = 'testmap']"
     mode="f:FXSL">
      <xsl:param name="arg1"/>

      <xsl:value-of select=
       "if(lower-case($arg1) ne $arg1)
         then concat(' ', $arg1)
         else $arg1
       "/>
    </xsl:template>
</xsl:stylesheet>

上記の変換がソースXMLドキュメント(未使用)に適用されると、予想される正しい結果が生成されます。

「ユーザーライセンスコード」

注意事項

  1. FXSL関数/テンプレートのDVCバージョン str-map() を使用しています。これは、別の関数と文字列の2つの引数を取る高階関数(HOF)です。 str-map() は、文字列のすべての文字に関数を適用し、結果の連結を返します。

  2. lower-case()関数が使用されるため(XSLT 2.0バージョン)、ラテンアルファベットのみに制限されません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top