.NET 6加载xsltc.exe编译XSLT程序集报SqlXml找不到错误
问题根因
- 你使用的
xsltc.exe是随.NET Framework 4.8 SDK分发的编译工具,它生成的预编译程序集强绑定.NET Framework专属运行时依赖,其中就包含仅在.NET Framework中存在的System.Data.SqlXml程序集。.NET Core、.NET 5及后续版本没有提供这个程序集及对应的内部辅助类型,因此加载时会直接抛出文件找不到的异常。 - 你对官方文档的表述存在理解偏差:文档中“脚本块仅在.NET Framework中支持”的说明,指的是.NET 5+自带的XSLT运行时不支持解析执行XSLT里的脚本块,并不代表.NET Framework平台下的xsltc工具编译出的二进制程序集可以直接跨框架在.NET 5+环境下运行。两个平台下的
XslCompiledTransform内部实现、编译生成的IL代码绑定的底层类型完全不兼容,和你的样式表有没有用脚本块、功能复不复杂没有任何关系。 - 从异常堆栈也能印证这一点:加载预编译类型时,运行时尝试通过反射绑定预编译代码引用的.NET Framework专属方法,因为找不到对应依赖项直接抛出异常。
可行解决方案
方案1:运行时直接加载XSLT源文件(推荐)
你已经验证过这个方式可以正常运行,直接在代码里调用Load方法传入XSLT文件路径即可:
var xslCompiledTransform = new XslCompiledTransform(); // 直接加载源XSLT文件,.NET 6运行时会自动完成编译 xslCompiledTransform.Load(@"..\..\..\Stylesheet.xsl"); xslCompiledTransform.Transform(@"..\..\..\input.xml", @"..\..\..\output.xml");
这个方案不存在兼容性问题,XslCompiledTransform在调用Load时本身就会在运行时将XSLT编译为IL指令执行,和xsltc预编译的执行效率完全一致,仅在首次加载样式表时会产生极短的编译耗时,对于绝大多数场景没有可感知的性能影响。
如果不想在发布时单独携带XSLT源文件,可以将XSLT文件作为嵌入资源打包到项目程序集中,运行时从资源流读取加载即可。
方案2:构建时预编译适配.NET 6的样式表程序集
.NET 6及后续版本没有提供独立的xsltc.exe命令行工具,但你可以自行实现一个简单的构建时编译工具:在工具中调用XslCompiledTransform提供的编译接口,将XSLT编译为适配当前.NET版本的程序集,供主项目引用。注意这种方式编译出的程序集只能在同版本或更高版本的.NET运行时中使用,不能和.NET Framework的预编译程序集混用,普通业务场景完全没必要做这层额外封装。
方案3:多目标条件适配
如果你的项目需要同时兼容.NET Framework和.NET 6,可以通过条件编译区分运行环境:
- 在.NET Framework环境下,继续使用原有xsltc预编译的DLL,通过
Load(Type)的方式加载 - 在.NET 6及以上环境下,切换为直接加载XSLT源文件的逻辑
注意:不存在任何可以直接让.NET Framework版本xsltc编译的DLL在.NET 6下运行的适配方法,不要尝试手动复制System.Data.SqlXml等.NET Framework专属程序集到.NET 6项目目录,这类程序集依赖.NET Framework的核心运行时,无法在.NET Core/.NET 5+下加载运行,纯浪费时间。
内容的提问来源于stack exchange,提问作者Ecoliat
相关产品推荐
相关产品推荐

