問題は、リンク作成テンプレートが間違った動作をすることです。
正しいことは、ID テンプレートを使用して<li>
、要素のテキスト ノードの子孫専用のテンプレートを作成することです。
これを試して:
<xsl:variable
name="keywords"
select="document('../../documents/main/keywords.xml')/keywords/keyword"
/>
<!-- the identity template does copies of everything not matched otherwise -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- text nodes in <li> elements get special treatment -->
<xsl:template match="li//text()">
<xsl:call-template name="markup">
<xsl:with-param name="phrases" select="$keywords"/>
<xsl:with-param name="first-only" select="false()"/>
</xsl:call-template>
</xsl:template>
<!-- marks up the current node -->
<xsl:template name="markup">
<xsl:with-param name="phrases" />
<xsl:with-param name="first-only" select="true()" />
<!-- you can use . here - no need to pass in a $text param -->
</xsl:template>
ID テンプレートは、このような問題をうまく解決するための鍵です。と のコピー<li>
を<b>
透過的に処理します。
- より具体的なテンプレートが現在のノードと一致しない限り、入力を完全に走査してコピーします。
- つまり、変更したいノードのテンプレートを作成するだけで済みます。この場合、ネストされた子を持つことができないため、一致するテキスト ノードが最適に機能します。
- のような名前付きテンプレートは避けてください
<xsl:template name="List">
。これは「プッシュ スタイル」の XSLT です。つまり、これは必須であり、非常にぎこちない結果になることがよくあります。
- は
<xsl:template match="li//text()">
ノードをストリームから取り出し、単にコピーするよりも複雑なことを行います。これは「プル スタイル」の XSLT、つまりテンプレート マッチングです。通常は、より扱いやすく、よりクリーンな XSLT コードが生成されます。
<li>
もちろん、要素内のテキスト ノードに制約されるわけではありません。マッチ式を変更して、他のノードに影響を与えるだけです。
他のテンプレートを中断することなく、すべての<b>
ノードを に変更したいとします。<strong>
プル スタイルでは、これは次のように簡単です。
<xsl:template match="b">
<strong>
<xsl:apply-templates select="node() | @*" />
<strong>
</xsl:template>
また、 を実行しても現在のノードは変更されないことに注意してください<xsl:call-template>
。したがって、呼び出されたテンプレートに現在のノードを渡す必要はありません。