构建服务器会像我在本地做的那样编译 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");
目前我正在使用XslCompiledTransform.Load()方法,带有一个“Type”参数,来引入基于xsltc.exe预编译的XSLT样式表。从堆栈跟踪中可以看出,.NET框架正在使用XmlUrlResolver尝试解析这些外部样式表的实际位置,但我没有找到一种方法提供重写的XmlResolver实现,其中我可以传递指向Web服务器上这些样式表所在位置的新baseUri。
我认为我可以通过不再使用xsltc.exe进行预编译,并通过XmlReaders加载XSLT样式表来解决这个问题,因为这将让我使用其他XslCompiledTransform.Load()方法,这些方法具有一个参数,我可以提供自己的XmlResolver实现。但是,我喜欢预编译选项用于语法验证和性能,所以除非我绝对必须放弃它,否则我不想放弃它。
有没有一种方法可以使用xsltc.exe预编译这些XSLT样式表,但仍然提供一种在运行时明确声明基本URI以解决<xsl:include>
和<xsl:import>
元素的相对路径的方式?