I. XSLT 2.0 ソリューション:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="value">
<xsl:for-each select="tokenize(., ',')">
<value><xsl:value-of select="."/></value>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメントに適用された場合 (整形式のため修正!!!!):
<fields>
<field name="example">
<value>example,i,am,new,to,xslt</value>
</field>
</fields>
必要な正しい結果が生成されます。
<fields>
<field name="example">
<value>example</value>
<value>i</value>
<value>am</value>
<value>new</value>
<value>to</value>
<value>xslt</value>
</field>
</fields>
Ⅱ.XSLT 1.0 ソリューション:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="value" name="tokenize">
<xsl:param name="pText" select="."/>
<xsl:if test="string($pText)">
<value>
<xsl:value-of select=
"substring-before(concat($pText, ','), ',')"/>
</value>
<xsl:call-template name="tokenize">
<xsl:with-param name="pText" select=
"substring-after($pText, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
この変換を同じ XML ドキュメント (上記) に適用すると、同じ正しい結果が生成されます。
<fields>
<field name="example">
<value>example</value>
<value>i</value>
<value>am</value>
<value>new</value>
<value>to</value>
<value>xslt</value>
</field>
</fields>
説明:
アイデンティティ ルールを使用して、すべてを「そのまま」コピーします。
に一致する (ID テンプレートの) テンプレートをオーバーライドしvalue
ます。
解決策 I では、標準の XPath 2.0 関数を適切に使用しますtokenize()
。
ソリューション II では、名前付きテンプレートを使用して関数のようなものを実装します。これは、XPath 1.0/XSLT 1.0 で定義されてtokenize()
いないためです。tokenize()
ソリューション II では、便宜上、value
カンマ トークン化を実行する名前付きテンプレートと一致するテンプレートをマージしました。