Web アプリケーションのビルド プロセスの一環として、フル コンパイルを実行するたびにMicrosoft の xsltc.exeコンパイラでビルドされるように XSLT スタイルシートをセットアップしました。コードがコンパイルされ、同じ場所でホストされるため、ローカルでの開発中、これはうまく機能しました。しかし、これをビルド サーバーに配置すると、問題が発生しました。
ビルド サーバーは、私がローカルで行うのと同じように XSLT スタイルシートをコンパイルしますが、コンパイルされたコードを内部のステージング Web サーバーにデプロイするスクリプトが実行されます。これらのバイナリがコンパイルされた場所から移動する<xsl:import>
と、<xsl:include>
要素内の相対パスが正しく解決されなくなり、XSLT スタイルシートの実行時に次のような例外が発生します。
Could not find a part of the path 'e:\{PATH}\xslt\docbook\VERSION'.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.Xsl.Runtime.XmlQueryContext.GetDataSource(String uriRelative, String uriBase)
現在のコードの一般的な考え方は次のとおりです。
var xslt = new XslCompiledTransform();
xslt.Load(typeof(Namespace.XslTransforms.CompiledXsltStylesheet));
xslt.Transform("input.xml", "output.xml");
現在、xsltc.exe ベースのプリコンパイル済み XSLT スタイルシートを取り込むために、単一の「Type」パラメーターを指定して XslCompiledTransform.Load() メソッドを使用しています。スタック トレースから、.NET フレームワークが XmlUrlResolver を使用してこれらの外部スタイルシートの実際の場所を解決しようとしていることがわかりますが、新しいこれらのスタイルシートが存在する Web サーバー上の場所を指す baseUri。
これは、xsltc.exe で事前にコンパイルせず、XmlReaders を介して XSLT スタイルシートをロードすることで解決できると思います。これにより、独自の XmlResolver 実装を提供できるパラメーターを持つ他の XslCompiledTransform.Load() メソッドを使用できるようになるからです。 . ただし、構文の検証とパフォーマンスのためにプリコンパイル オプションが気に入っているので、絶対に必要でない限り、これを放棄したくありません。
<xsl:include>
xsltc.exe を使用してこれらの XSLT スタイルシートをプリコンパイルする方法はありますか?実行時に<xsl:import>
要素の相対パス解決のために baseUri を明示的に指定する方法を提供しますか?