I have an XSLT stylesheet "Stylesheet.xsl" that i have compiled to a "Stylesheet.dll" using xsltc.exe
That DLL is included in my .NET 6 (<TargetFramework>net6.0</TargetFramework>
) project and is used as follows:
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");
The Load
method throws an FileNotFoundException
with message "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."
The documentation on xsltc.exe says the following:
Script blocks are supported only in .NET Framework. They are not supported on .NET Core or .NET 5 or later.
This heavily imiplies that stylesheets compiled using xsltc.exe should work on .NET Core or .NET 5 or later (when no script blocks are use) but they don't in my test.
Does anyone know why stylesheets compiled using xsltc.exe do not work with .NET 6 and how to fix this?
I've added more details on what I tried below.
Note that the stylesheet Stylesheet.xsl
I use is very basic and uses no special functionality:
<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>
Command for generating the DLL:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\xsltc.exe" Stylesheet.xsl
Referencing the DLL in the SDK-style .csproj file:
<ItemGroup>
<Reference Include="Stylesheet">
<HintPath>.\Stylesheet.dll</HintPath>
</Reference>
</ItemGroup>
input.xml
:
<input>
<book title="First Title" />
<book title="Second Title" />
</input>
output.xml
when executing the transformation with the non-compiled stylesheet:
<output>
<booktitle>First Title</booktitle>
<booktitle>Second Title</booktitle>
</output>
I have researched and found other people having the same problem but haven't found a solution or an explanation on why the Microsoft Docs implicitly state it should work while it does not in my test.
Stack trace of the 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
Based on the information in the GitHub issue .NET 6 not support XslCompiledTransform.Load(type(myXsltCompiled_dll))
, it looks as if this is not supported, and won't be.
A comment on April 18, 2022 said:
The assembly
System.Data.SqlXml
contains the namespaceSystem.Xml.Xsl.Runtime
, which is not present in .NET Core.According to the porting guide,
msxsl:script
is unavailable on .NET Core. The .NET Framework specific tutorial is expected not to work.
A second person commented:
Looks like
System.Data.SqlXml
is part of SQLXML which is owned by the SQL Server org and as far as I know does not support .NET Core.
A third person replied:
There are currently no plans regarding SQLXML and support for .NET 5+, and we haven't heard many requests in this direction. I would recommend opening up a User Voice here to get some traction and consensus on the subject: https://aka.ms/sqlfeedback
So, that's your answer: "msxsl:script
is unavailable on .NET Core. The .NET Framework specific tutorial is expected not to work." and the reason is that a non-.NET group would have to make it possible, but doesn't have plans to. They don't perceive a demand.
And, they acknowledge that the documentation is misleading. It appears that a change was made to the docs in May 2022, and a pull request created: Note that XSLT script blocks are .NET Framework only.
I recognize that this does not provide a solution or a way forward for you, and that is disappointing. But this is the answer to your question: doing a transform this way simply isn't supported in .NET 6.0.