1

私は現在、主に HTML を表す単純なマークアップを持っています。

以下はその抜粋です

<li>Make this <b>Bold</b></li>

もちろん、タグが通過して自動的に太字で表示される<xsl:copy-of>ようにするために使用できますが、問題があります。<b>

キーワードまたはフレーズのリポジトリに対してマークアップをチェックする別の XSL を使用しており、それらが存在する場合はリンクが作成されます。

以下は私のXSLです

<xsl:template name="List" match="li">
  <li>
          <xsl:call-template name="markup">
            <xsl:with-param name="text" select="."/>
            <xsl:with-param name="phrases" select="document('../../documents/main/keywords.xml')/keywords/keyword"/>
            <xsl:with-param name="first-only" select="false()"/>
          </xsl:call-template>
  </li>
  </xsl:template>

このメソッドは、子タグが通過するのを防ぎますが、これを回避する方法がわかりません。

どんな助けでも大歓迎です!ダン

4

1 に答える 1

1

問題は、リンク作成テンプレートが間違った動作をすることです。

正しいことは、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>透過的に処理します。

  1. より具体的なテンプレートが現在のノードと一致しない限り、入力を完全に走査してコピーします。
  2. つまり、変更したいノードのテンプレートを作成するだけで済みます。この場合、ネストされた子を持つことができないため、一致するテキスト ノードが最適に機能します。
  3. のような名前付きテンプレートは避けてください<xsl:template name="List">。これは「プッシュ スタイル」の XSLT です。つまり、これは必須であり、非常にぎこちない結果になることがよくあります。
  4. <xsl:template match="li//text()"> ノードをストリームから取り出し、単にコピーするよりも複雑なことを行います。これは「プル スタイル」の XSLT、つまりテンプレート マッチングです。通常は、より扱いやすく、よりクリーンな XSLT コードが生成されます。
  5. <li>もちろん、要素内のテキスト ノードに制約されるわけではありません。マッチ式を変更して、他のノードに影響を与えるだけです。

他のテンプレートを中断することなく、すべての<b>ノードを に変更したいとします。<strong>プル スタイルでは、これは次のように簡単です。

<xsl:template match="b">
  <strong>
    <xsl:apply-templates select="node() | @*" />
  <strong>
</xsl:template>

また、 を実行しても現在のノードは変更されないことに注意してください<xsl:call-template>。したがって、呼び出されたテンプレートに現在のノードを渡す必要はありません。

于 2012-04-26T08:59:35.873 に答える