В рамках процесса сборки нашего веб-приложения я настроил таблицы стилей XSLT для сборки с помощью всякий раз, когда мы запускаем полную компиляцию. Во время локальной разработки это отлично сработало, так как код компилируется и размещается в одном и том же месте. Однако, как только это было помещено на сервер сборки, возникли проблемы.
Сервер сборки скомпилирует таблицы стилей XSLT точно так же, как я делаю локально, но затем запустится скрипт, который развернет скомпилированный код на нашем внутреннем промежуточном веб-сервере. После перемещения этих двоичных файлов из того места, где они были скомпилированы, относительные пути в элементах <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");
Прямо сейчас я использую метод XslCompiledTransform.Load() с одним параметром «Тип», чтобы добавить предварительно скомпилированные таблицы стилей XSLT на основе xsltc.exe. Из трассировки стека я могу сказать, что платформа .NET использует XmlUrlResolver, чтобы попытаться разрешить фактическое расположение этих внешних таблиц стилей, но я не вижу способа предоставить переопределенную реализацию XmlResolver, где я мог бы передать новый baseUri, который указывает, где эти таблицы стилей находятся на веб-сервере.
Я предполагаю, что смогу решить эту проблему, отказавшись от предварительной компиляции с помощью xsltc.exe и загрузив таблицы стилей XSLT через XmlReaders, поскольку это позволит мне использовать другие методы XslCompiledTransform.Load(), у которых есть параметр, в котором я мог бы предоставить свою собственную реализацию XmlResolver. Однако мне нравится вариант предварительной компиляции для проверки синтаксиса и производительности, поэтому я не хочу отказываться от него, если только в этом нет крайней необходимости.
Есть ли способ использовать xsltc.exe для предварительной компиляции этих таблиц стилей XSLT, но при этом предоставить способ явного указания baseUri для разрешения относительного пути элементов <xsl:include>
и <xsl:import>
во время выполнения?