【发布时间】:2019-10-07 13:27:35
【问题描述】:
有没有人在 2019 年在 .NET Core 2.x+ 中使用 XSLT3 转换?
似乎向 MS 提出的XSLT2/3 support 请求没有向前推进,而撒克逊人还有其他优先事项,尤其是考虑到IKVM closedown。
对于进程内 XSLT 转换还有其他替代方法吗?目前,我唯一的选择似乎是通过外部服务或一些不受欢迎的(对我们而言)COM 风格的方法来封装一些东西,这会涉及大量数据编组,从而损害性能。
【问题讨论】:
有没有人在 2019 年在 .NET Core 2.x+ 中使用 XSLT3 转换?
似乎向 MS 提出的XSLT2/3 support 请求没有向前推进,而撒克逊人还有其他优先事项,尤其是考虑到IKVM closedown。
对于进程内 XSLT 转换还有其他替代方法吗?目前,我唯一的选择似乎是通过外部服务或一些不受欢迎的(对我们而言)COM 风格的方法来封装一些东西,这会涉及大量数据编组,从而损害性能。
【问题讨论】:
不幸的是,IKVM 从未支持 .NET Core,因此无法使 Saxon 的 .NET 版本在该环境中工作。在 Saxonica,我们一直在探索 .NET 支持的替代途径,但我们还没有发现任何有希望的东西。 (有人喜欢为 .NET 实现 Kotlin 吗?)
我不知道使用 XMLPrime 或 Exselt 有什么可能,两者都针对 .NET。
2021 年更新
Saxonica 现在在 .NET 5 上发布 SaxonCS,该产品是通过使用自定义转译器将 SaxonJ 的 Java 代码转换为 C# 源代码而构建的。
【讨论】:
SaxonCS EE 已发布,可与 .NET 5 和 .NET 6(RC/预览版)一起使用,这样就可以将 XSLT 3、XPath 3.1 和 XQuery 3.1 与 .NET Core 一起使用。然而,它只能在商业许可下使用,但您可以使用试用许可对其进行测试,从 Saxonica 下载的地址为 https://www.saxonica.com/download/dotnet.xml,在 NuGet 上的下载地址为 https://www.nuget.org/packages/SaxonCS/。
【讨论】:
有一种方法可以在 .NET Core 上使用 Saxon:通过 Transform.exe 作为进程运行。
你可以使用类似这样的代码:
/// <summary>Transform XML inputFile using xsltFile and parameters. Save the result to the outputFile.</summary>
public void Transform(string inputFile, string outputFile, string xsltFile, NameValueCollection parameters)
{
//Search for the instalation path on the system
string path = GetInstalPath(@"Software\Saxonica\SaxonHE-N\Settings", "InstallPath");
string exePath = Path.Combine(path, "bin", "Transform.exe");
string parametersCmd = null;
//Set indicidual parameters
foreach (string parameter in parameters)
{
parametersCmd += String.Format("{0}={1} ", parameter, parameters[parameter]);
}
//set arguments for Transform.exe
string arguments = string.Format("-s:\"{1}\" -xsl:\"{0}\" -o:\"{3}\" {2}", xsltFile, inputFile, parametersCmd, outputFile);
//https://stackoverflow.com/questions/5377423/hide-console-window-from-process-start-c-sharp
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = exePath;
startInfo.Arguments = arguments;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
int waitingTime = 5 * 60 * 1000; //5 minutes; time in milliseconds
Process processTemp = new Process();
processTemp.StartInfo = startInfo;
processTemp.EnableRaisingEvents = true;
try
{
processTemp.Start();
processTemp.WaitForExit(waitingTime);
}
catch (Exception e)
{
throw;
}
}
static string GetInstalPath(string comName, string key)
{
RegistryKey comKey = Registry.CurrentUser.OpenSubKey(comName);
if (comKey == null)
return null;
string clsid = (string)comKey.GetValue(key);
return clsid;
}
【讨论】: