1. ホーム
  2. xslt

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

2023-09-10 11:10:52

質問

こんにちは、私はそれが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ファイルに存在する全ての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>

なぜ以前のコードはテキストを出力し、なぜ私は他のすべてのテキストを無視するようにXSLを主張しなければならないのですか? それはすべてのXMLパーサーまたは私自身の動作(私はmsxmlパーサーを使用しています)だけです。

どのように解決するのですか?

<ブロッククオート

なぜ以前のコードはテキストを出力したのでしょうか? を無視するようにXSLに要求する必要があるのでしょうか? 他のテキストを無視するようXSLに要求しなければならないのでしょうか? XMLパーサーの挙動なのか、それとも私のパーサーの挙動なのか?

あなたは、仕様で指定されている最も基本的な XSLT 機能の 1 つである の組み込みテンプレートです。 .

から 仕様 :

組み込みのテンプレートルールがあり 再帰的な処理の継続を許可する パターンマッチが成功しない場合 の明示的なテンプレート規則によって が存在する。このテンプレート規則 は,要素ノードとルートノードの両方に適用される。 ルートノードの両方に適用される。以下は 組み込みテンプレートに相当する ルールに相当するものを示します。

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

また、各モードには組み込みのテンプレートルール があり、これによって再帰的な 処理に成功しなかった場合、同じ モードでの再帰的処理の継続を可能にします。 パターンマッチが成功しない場合に、同じモードで再帰的な処理を続けることができます。 ルールによってパターンマッチが成功しない場合に,再帰的な処理を同じモードで継続できるようにする。このテンプレート ルールは,要素ノードとルートノードの両方に適用される。 ルートノードの両方に適用される。以下は 組み込みテンプレート ルールに相当します.

<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 デザインパターンです。 をオーバーライドして、呼び出されるたびにエラーメッセージを発行し、プログラマーが自分の変換が "leaking" であることをすぐに知ることができるようにするのが良い 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"/> は警告となる。