質問
小文字と大文字の境界でタグを分割することは可能ですか? たとえば、タグ「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ドキュメント(未使用)に適用されると、予想される正しい結果が生成されます。
「ユーザーライセンスコード」
注意事項:
-
FXSL関数/テンプレートのDVCバージョン
str-map()
を使用しています。これは、別の関数と文字列の2つの引数を取る高階関数(HOF)です。str-map()
は、文字列のすべての文字に関数を適用し、結果の連結を返します。 -
lower-case()関数が使用されるため(XSLT 2.0バージョン)、ラテンアルファベットのみに制限されません。