XSLT がデフォルトですべてのテキストを出力するのはなぜですか? 質問する

XSLT がデフォルトですべてのテキストを出力するのはなぜですか? 質問する

こんにちは。タグが null の場合にタグを削除する変換を実行しました。

変換が正常に動作しているかどうかを確認したかったので、手動で確認する代わりに、OUTPUT XML に特定のタグが存在するかどうかをチェックする XSLT コードをもう 1 つ作成しました。このタグが null の場合、2 番目の XSLT はテキスト「FOUND」を出力する必要があります。(実際には XML 形式の出力は必要ありませんが、検索には XSLT を使用しているだけです。)

この XSL コードを試してみたところ::

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
      FOUND
  </xsl:template>
</xsl:stylesheet>

XMLファイルに存在するすべてのテキストデータを出力します。

それを避けるために、次のコードを書く必要がありました::

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/SiebelMessage//SuppressCalendar[.!='']">
      FOUND
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>

前のコードが TEXT を出力するのはなぜですか。XSL に他のすべてのテキストを無視するように要求する必要があるのはなぜですか。これはすべての XML パーサーの動作ですか、それとも私の独自の動作だけですか (私は msxml パーサーを使用しています)。

ベストアンサー1

前のコードではなぜTEXTが出力されるのでしょうか。なぜXSLに他のすべてのテキストを無視するように要求する必要があるのでしょうか。これはすべてのXMLパーサーの動作ですか、それとも私の独自の動作ですか。

仕様書に規定されている最も基本的なXSLT機能の1つを発見しました。XSLTの組み込みテンプレート

からスペック:

スタイルシート内の明示的なテンプレート ルールによってパターン マッチが成功しない場合でも再帰処理を続行できるようにする組み込みテンプレート ルールがあります。このテンプレート ルールは、要素ノードとルート ノードの両方に適用されます。次に、組み込みテンプレート ルールと同等のものを示します。

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

各モードには組み込みテンプレート ルールもあり、これにより、スタイルシート内の明示的なテンプレート ルールによるパターン マッチが成功しない場合でも、同じモードで再帰処理を続行できます。このテンプレート ルールは、要素ノードとルート ノードの両方に適用されます。次に、モード m の組み込みテンプレート ルールと同等のものを示します。

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

テキストおよび属性ノード用の組み込みテンプレート ルールもあり、テキストを次のようにコピーします。

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

処理命令とコメントの組み込みテンプレート ルールは、何もしないことです。

<xsl:template match="processing-instruction()|comment()"/>

名前空間ノードの組み込みテンプレート ルールも何も行いません。名前空間ノードに一致するパターンは存在しないため、組み込みテンプレート ルールは名前空間ノードに適用される唯一のテンプレート ルールです。

組み込みテンプレート ルールは、スタイルシートの前に暗黙的にインポートされたかのように扱われるため、他のすべてのテンプレート ルールよりもインポートの優先順位が低くなります。したがって、作成者は明示的なテンプレート ルールを含めることで組み込みテンプレート ルールをオーバーライドできます。

したがって、報告された動作は、組み込みテンプレート (3 つのうち 1 番目と 2 番目) を適用した結果です。

組み込みテンプレートをオーバーライドするのは良いXSLTデザインパターンです呼び出されるたびにエラー メッセージを発行する独自のコードを使用すると、プログラマは変換が「リーク」していることをすぐに知ることができます。

例えば次の XML ドキュメントがある場合:

<a>
  <b>
    <c>Don't want to see this</c>
  </b>
</a>

そしてこの変換によって処理される:

<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="a|b">
   <xsl:copy>
      <xsl:attribute name="name">
        <xsl:value-of select="name()"/>
      </xsl:attribute>
      <xsl:apply-templates/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

結果は:

<a name="a">
   <b name="b">Don't want to see this</b>
</a>

プログラマーは、不要なテキストがどのように表示されたのか非常に混乱することになります。

しかし、これを追加するだけでcatch-all template混乱を避け、エラーをすぐに見つけるのに役立ちます:

 <xsl:template match="*">
  <xsl:message terminate="no">
   WARNING: Unmatched element: <xsl:value-of select="name()"/>
  </xsl:message>
  
  <xsl:apply-templates/>
 </xsl:template>

今では、混乱を招く出力の他に、プログラマーは問題をすぐに説明する警告を受け取る。:

 WARNING: Unmatched element: c

Michael Kay による XSLT 3.0 への後日の追加

XSLT 3.0 では、包括的なテンプレート ルールを追加するのではなく、宣言でフォールバック動作を指定できますxsl:mode。たとえば、<xsl:mode on-no-match="shallow-skip"/>は一致しないすべてのノード (テキスト ノードを含む) をスキップしますが、 は<xsl:mode on-no-match="fail"/>一致しない場合はエラーとして扱い、<xsl:mode warning-on-no-match="true"/>警告を出力します。

おすすめ記事