なにもしないXSLT

時々必要になって作るのだが、その度にひっかかるのがこの「何もしないXSLT

分かってしまうとどうと言うことがないのでここに晒しておく。(ファイルをどこに置いたか分からなくなって毎回作り直している。)割とややこしいXMLで問題が出てないからこれでいけるはず。なお、xslはXSLTのネームスペースに対応付けされている前提。

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

なぜ必要になるかというと、「基本的に元のXMLのままだが数箇所を機械的に変更したい」という処理はこれをベースに作ることになるからである。

よくひっかかるのは属性の処理とテキストノードの処理。apply-templatesで明記しないと無視されてしまう。*1

属性のテンプレートは分けて書かなくても動いた記憶があるが、どうも気持ち悪いので別にした(笑)

text()に付いてのテンプレートを書いていないのだが、XSLTの標準処理でtext()はそのまま出てくるというのがあるので問題ない。



なお、本当に何もしないし役に立たないのは

<xsl:template match="/">
    <xsl:copy-of select="." />
</xsl:template>

である(笑)。構造をたどりもしないので一瞬で終わるはず。



だが、

<xsl:template match="要素名">
    <xsl:copy-of select="." />
</xsl:template>

を「何もしないXSLT」に付け加えると、その要素名以下は構造をたどっていくこともせずにコピーするので処理が早くなったりする効果はある。処理対象が含まれない部分をcopy-ofで飛ばしていくと速くなるはず。



(追記)

<xsl:apply-templates select="*|@*|text()" />

の替わりに

<xsl:apply-templates select="@*" />
<xsl:apply-templates />

と書く例を見た。なるほど、属性は必ず前に付くから分けて処理していいし、分けて処理するならselectは既定値のままでいいのか。

*1:正確に言うとテキストノードの処理は組み込みのapply-templatesのルールで処理されるものなのだが、組み込みでは処理されない要素と属性を処理してもらうためにそれをselect属性に明記してしまうと、逆に組み込みの処理であるテキストノードの処理は走らなくなってしまうのでそれも明記する必要がでてくるのだ。