Search code examples
c#.netxml.net-corexslt

Use xsltc.exe generated assembly (XSLT stylesheet) in .NET 6


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?


More details

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

Solution

  • 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 namespace System.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.