web-dev-qa-db-ja.com

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

こんにちは、タグがnullの場合、タグをドロップする変換を実行しました。

変換が正常に機能しているかどうかを確認したかったので、手動でチェックする代わりに、出力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ファイルに存在するすべてのTEXT DATAを出力し、

それを避けるために、私はこのコードを書かなければなりませんでした::

<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パーサーを使用しています)。

71

前のコードが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

XSLT 3.0のMichael Kayによる後期追加

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"/>は警告になります。

146

XSLには テンプレートルールに組み込まれている がいくつかあり、そのうちの1つは次のとおりです。

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

テキストを出力します。

14
Oded