参照された XSL テンプレートでスクリプトを作成するためのアセンブリの使用
-
20-09-2019 - |
質問
XSL ファイルは 2 つあります。1 つは、 <xsl:include>
. 。メイン テンプレートは、ノード値に応じて呼び出す実際のテンプレートを決定し、含まれるテンプレートには実際の変換ルールが含まれます。ここでは特別なことは何もありません。
ただし、インクルードされたファイルにはスクリプト ブロックが含まれています。
<msxsl:script language="VB" implements-prefix="user">
<msxsl:assembly href="C:\Absolute\Path\MyEscaper.dll" />
<msxsl:using namespace="ZebraEscaper.MyCompany" />
<![CDATA[
Public Function escape(s As String) As String
Return EncodeField(s, True)
End Function
]]>
</msxsl:script>
user:escape() 関数は、後で付属のテンプレートで使用されます。
次に、VS2008 XSLT デバッガーに移動します。
メインのテンプレート呼び出し <xsl:apply-templates>
含まれているテンプレートが実行されます。そして、FileNotFound 例外が発生します。「ファイルまたはアセンブリ 'MyEscaper、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null'、またはその依存関係の 1 つを読み込めませんでした。」システムは、指定されたファイルを見つけることができません。"
ここで、インクルードされたファイルだけにアクセスして、それがスタンドアロンのテンプレートであり、どこにもインクルードされていないかのように実行すると、すべてが機能します。アセンブリが検出され、関数が呼び出されますが、包含されるように設計されたテンプレートとしては明らかに結果が意味をなしません。
そこで質問ですが、テンプレートが含まれているのにシステムがアセンブリを見つけられないのはなぜでしょうか?
詳しくは
ドキュメントでは、「アセンブリパス名は2回解決されます - 編集中に1回、実行中に1回」と述べています。私が意図的にパスでタイプミスをした場合、私は同じfilenotfoundの例外を取得しますが、システムが見つけることができないと言っている場所では異なってフォーマットされました file://C:\Absolute\Path\MyEscaper.dll. 。ただし、パスが正しい場合、例外は見つからなかったと主張します。 MyEscaper.dll、バージョン = blabla、パブリック トークン = null, 、その例外は .Net によって作成された CompiledStylesheet.dll で発生します。コンパイルされたスタイルシートは、href ではなく名前でアセンブリを呼び出すように指示されていると思いますが、アセンブリは一時フォルダーにないため、呼び出しは失敗します。
なぜそうなのか?絶対パスが相対パスに (誤って) 変換されるのはどこで、なぜですか。また、それを制御するにはどうすればよいですか?
解決
それで。
何らかの理由で、組み込まれたシナリオでは、アセンブリへのパスがコンパイル中と実行中に異なる方法で解決されます。なぜそうなるのか、私には見当がつきません。
まともな解決策は 2 つだけ見つかりました。
すべてのコードを参照アセンブリから XSL テンプレートに移動し、埋め込みスクリプトにします。小さなヘルパー関数の場合は、実際にはこれが推奨されます。さもないと、
参照されたアセンブリに厳密な名前で署名し、それを GAC に追加し、次を使用してテンプレートから参照します。
name
, 、 ないhref
. 。こうすることで、アセンブリはコンパイル中および実行中に同じ方法で検索され、見つかります。