18

完全な説明の前にそれらを読みたい場合は、私の質問はこの投稿の最後にあります。

XSL を使用して XML ドキュメントをきれいな Web ページに変換していますが、変数を正しく渡すことができません。多くxsl:templateの が定義されており、そのうちの 1 つだけに特定のパラメーターを渡す必要があります。おそらくすべての に送信される名前付きパラメーターを渡すことができることを望んでいましたがxsl:template、1つだけで使用され、他の人には無視されます。しかし、これを自分自身 (および XSL に関する私の限られた理解) でテストしようとすると、パラメーターをまったく渡すことができず、ましてや他xsl:templateの s を誤って妨害していないかどうかをテストすることもできませんでした。

以下は単純化されたコード例です (この質問のために入力したものです。1 つまたは 2 つのタイプミスが含まれている可能性があります)。xsl:templateXML のノードを処理するためにさまざまなが定義されており、今まではすべて正常に機能していました。私が問題を抱えているように見えるのは、これらのテンプレートにパラメーターを追加することです。

XML ファイル:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="main.xsl"?>
<wrapperNode>
  <testNode>
    <subNode/>
  </testNode>
</wrapperNode>

main.xsl:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="test.xsl"/>
<xsl:output method="html" indent="yes"/>

<xsl:template match="/">

<html>
  <body>
      <xsl:apply-templates>
        <xsl:with-param name="testParam">TEST_PARAMETER</xsl:with-param>
      </xsl:apply-templates>
  </body>
</html>

</xsl:template>
</xsl:stylesheet>

test.xsl:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="testNode">
  <xsl:param name="testParam" />
  TEST1
  <xsl:value-of select="$testParam" />
  TEST2
</xsl:template>
</xsl:stylesheet>

出力 (実際):

TEST1 TEST2

出力 (期待/望ましい):

TEST1 TEST_PARAMETER TEST2

これに関する私の質問:

  1. with xsl:templateを使用してすべての s に名前付きパラメーターを送信することは可能ですが 、実際のテンプレート内でこの値を具体的に選択して、単一のテンプレートで明示的に使用し、他のすべてのテンプレートで無視できるようにします (追加したい場合でも)後で他のテンプレート用の別の名前のパラメーター)?xsl:apply-templatesxsl:with-paramname=

  2. パラメーターをまったく受け取っていないように見える現在のサンプル コードの何が間違っていますか?

  3. これを達成するためのより良い方法はありますか?

編集:test.xsl :testNodeテンプレート内の他の出力により、それが正常に呼び出されていることを確認していることを明確にしたいと思います。機能していないのはパラメーター部分のみです。そのテンプレートが呼び出されない理由を理解するために人々の時間を無駄にするつもりはありません。です。

更新:最初に受け取った回答に応えて、私が作成した例は完全に正しくなく (私の間違い)、問題を明確に示していなかった (つまり、正しいテンプレート呼び出されているが、それパラメータが機能していないようです)、例をより良いものに置き換えました。この例は、testNodeテンプレートが正常に呼び出されていることをより明確に示していますが、パラメーターは渡されていないようです。この質問に対する以前の回答を検討する前後に、これを何度もテストしました。私が他の場所で読んだことや人々がこれまでに提案したことからすべてが正しいように見えるので、私は完全に困惑しています.

4

3 に答える 3

33

これに関する私の質問:

  1. xsl:with-param で xsl:apply-templates を使用してすべての xsl:templates に名前付きパラメーターを送信することは可能ですか?単一のテンプレートであり、他のすべてによって無視されます (後で他のテンプレートに別の名前のパラメーターを追加したい場合でも)?

はい。XSLT 2.0 では、いわゆる「トンネル パラメーター」を使用できますが、XSLT 1.0 では、これは、一部のパラメーターがチェーンの下流にあるリモート テンプレートに到達する方法です。

もう 1 つの方法は、チェーン内のすべてのテンプレートを通過する必要がないように、グローバル パラメーターを使用することです。

.2. パラメーターをまったく受け取っていないように見える現在のサンプル コードの何が間違っていますか?

その理由は、あなたが私たちに見せていないコードにあります。または、実際のケースで使用しているソース XML ドキュメントが、ここで提供されているものと同じではない可能性があります。提供されたコードを実行しましたが、問題をまったく再現できませんでした。目的の出力が生成されます。

私の推測では、一致するテンプレートの前に他のテンプレートが選択されていると思いtestNodeます。このテンプレートは、渡されたパラメーターについて何も認識せず、それを適用するテンプレートに渡しません。したがって、パラメータはテンプレート マッチングにまったく渡されませんtestNode

私の推測では、次のように置き換えた場合:

  <xsl:apply-templates> 
    <xsl:with-param name="testParam">TEST_PARAMETER</xsl:with-param> 
  </xsl:apply-templates> 

  <xsl:apply-templates select="testNode"> 
    <xsl:with-param name="testParam">TEST_PARAMETER</xsl:with-param> 
  </xsl:apply-templates> 

目的の出力を得ることができます。

また、XSLT デバッガー (Visual Studio のものなど) を使用してトレースし、どのテンプレートが選択されているかを正確に確認することもできます。

.3. これを達成するためのより良い方法はありますか?

先に述べたように、代わりにグローバル パラメータを使用することもできますが、これが優れているかどうかはわかりません。

最後に、問題を再現できないコードを実行しました。

XSLT スタイルシート:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>

 <xsl:template match="/">
      This is text1
      <xsl:apply-templates>
        <xsl:with-param name="testParam">TEST_PARAMETER</xsl:with-param>
      </xsl:apply-templates>
      This is text2
 </xsl:template>

 <xsl:template match="testNode">
  <xsl:param name="testParam" />
  <xsl:value-of select="$testParam" />
 </xsl:template>
</xsl:stylesheet>

XML ドキュメント:

<?xml-stylesheet type="text/xsl" href="main.xsl"?>
<testNode>
  <subNode/>
</testNode>

結果:

  This is text1
  TEST_PARAMETER
  This is text2

アップデート:

OPは、私の推測を証明するより正確な情報を提供しました。

これで、要素ノードのXSLT 組み込みテンプレートを で選択できるようにしたことが問題の原因であることが明らかになりましたwrapperNode。当然、このテンプレートはパラメーターを認識せず、testParamパラメーターを使用せず、このパラメーターを渡しません。したがって、<xsl:apply-templates/>組み込みテンプレートの により、testNodeパラメーターを渡さずにテンプレート マッチングが選択されます。これは、報告された動作/結果を説明しています。

解決策wrapperNode: 解決策は、名前付きパラメーターを受け入れ、テンプレートtestParamを適用するときにそれを渡すテンプレート マッチングを指定することです。

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes"/>

 <xsl:template match="/">
  <html>
    <body>
        <xsl:apply-templates>
          <xsl:with-param name="testParam" select="'TEST_PARAMETER'"/>
        </xsl:apply-templates>
    </body>
  </html>
 </xsl:template>

 <xsl:template match="testNode">
  <xsl:param name="testParam" />
  TEST1
  <xsl:value-of select="$testParam" />
  TEST2
 </xsl:template>

 <xsl:template match="wrapperNode">
  <xsl:param name="testParam" />

  <xsl:apply-templates>
   <xsl:with-param name="testParam" select="$testParam"/>
  </xsl:apply-templates>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、期待される結果が生成されます。

<html>
<body>
  TEST1
  TEST_PARAMETER
  TEST2
 </body>
</html>
于 2010-11-18T23:11:20.830 に答える
1

<html>および<body>タグは、XSL スタイルシート内にある場所では使用できません。それらと終了タグを削除し、これを Oxygen/XML で実行すると、「目的の」出力が得られます。これらのタグを最上位テンプレートの内側に配置したいと思います。その場合、htmlおよびbodyタグ内に出力が生成されます。

無効なスタイルシートについて文句を言わなかった、どの XSLT エンジンを使用しましたか?

于 2010-11-18T22:06:19.437 に答える