我有一个 XSLT 样式表“Stylesheet.xsl”,我已使用 xsltc.exe 将其编译为“Stylesheet.dll”
该 DLL 包含在我的 .NET 6 (
<TargetFramework>net6.0</TargetFramework>
) 项目中,用法如下:
var xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(typeof(Stylesheet));
// ↑ System.IO.FileNotFoundException: Could not load file or assembly 'System.Data.SqlXml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. The system cannot find the file specified.
xslCompiledTransform.Transform(@"..\..\..\input.xml", @"..\..\..\output.xml");
Load
方法抛出FileNotFoundException
,并显示消息“无法加载文件或程序集‘System.Data.SqlXml,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089’。系统找不到指定的文件。 ”
关于 xsltc.exe 的文档说明了以下内容:
脚本块仅在 .NET Framework 中受支持。 .NET Core 或 .NET 5 或更高版本不支持它们。
这严重暗示使用 xsltc.exe 编译的样式表应该在 .NET Core 或 .NET 5 或更高版本上工作(当不使用脚本块时),但在我的测试中却不起作用。
有谁知道为什么使用 xsltc.exe 编译的样式表不适用于 .NET 6 以及如何解决此问题?
更多详情
请注意,我使用的样式表
Stylesheet.xsl
非常基本,没有使用特殊功能:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="/">
<output>
<xsl:for-each select="input/book">
<booktitle>
<xsl:value-of select="@title" />
</booktitle>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
生成DLL的命令:"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\xsltc.exe" Stylesheet.xsl
在 SDK 样式的 .csproj 文件中引用 DLL:
<ItemGroup>
<Reference Include="Stylesheet">
<HintPath>.\Stylesheet.dll</HintPath>
</Reference>
</ItemGroup>
input.xml
:
<input>
<book title="First Title" />
<book title="Second Title" />
</input>
output.xml
使用未编译的样式表执行转换时:
<output>
<booktitle>First Title</booktitle>
<booktitle>Second Title</booktitle>
</output>
我已经研究并发现其他人也有同样的问题,但还没有找到解决方案或解释为什么 Microsoft 文档隐式声明它应该可以工作,而在我的测试中却不起作用。
System.IO.FileNotFoundException
的堆栈跟踪:
at System.Delegate.BindToMethodInfo(Object target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags)
at System.Reflection.RuntimeMethodInfo.CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags)
at System.Reflection.RuntimeMethodInfo.CreateDelegate(Type delegateType)
at System.Xml.Xsl.XslCompiledTransform.Load(MethodInfo executeMethod, Byte[] queryData, Type[] earlyBoundTypes)
at System.Xml.Xsl.XslCompiledTransform.Load(Type compiledStylesheet)
at TestXslDotnet6.Program.Main(String[] args) in C:\Users\UserNameRedacted\Path\To\Repo\TestXslDotnet6\TestXslDotnet6\Program.cs:line 10
,看起来好像不支持,也不会支持。 2022年4月18日的评论说:
程序集 System.Data.SqlXml 包含命名空间 System.Xml.Xsl.Runtime,该命名空间在 .NET Core 中不存在。
根据移植指南,msxsl:script 在 .NET Core 上不可用。 .NET Framework 特定教程预计不起作用。
第二个人评论:
看起来 System.Data.SqlXml 是 SQLXML 的一部分,属于 据我所知,SQL Server org 不支持 .NET Core。
第三个人回复:
目前没有关于 SQLXML 和对 .NET 5+ 支持的计划, 我们还没有听到很多这方面的请求。我会 建议在此处开放用户声音以获得一些吸引力并 关于该主题的共识:
https://aka.ms/sqlfeedback所以,这就是您的答案:“msxsl:script 在 .NET Core 上不可用。.NET Framework 特定教程预计不起作用。”原因是非 .NET 组织必须使其成为可能,但没有计划这样做。他们没有意识到需求。
而且,他们承认该文档具有误导性。似乎在 2022 年 5 月对文档进行了更改,并创建了拉取请求:
请注意,XSLT 脚本块仅限 .NET Framework我认识到这并没有为您提供解决方案或前进的道路,这令人失望。但这就是您问题的答案:.NET 6.0 根本不支持以这种方式进行转换。
因此,如果您想将 XslCompiledTransform 类与通过 xlstc.exe 生成的 dll 类型一起使用,请按照以下步骤操作:
xsltc.exe /class:Transform /out:Your.Assembly.dll
ildasm Your.Assembly.dll /out=Your.Assembly.ill
ilasm Your.Assembly.ill /dll