使用 Saxon 时如何停止样式表文件锁定?
How Do I Stop Stylesheet File Locking When Using Saxon?
我正在使用最新版本的 Saxon HE for .NET (9.7.0.18),我发现我的样式表文件被锁定的问题。这个问题并不总是立即发生,但我通常会在多次调用样式表后开始看到这个问题。到那时,在我回收应用程序池之前,我将无法再通过文本编辑器保存对相关样式表的更改。
据我目前所见,似乎通过 xsl:import 或 xsl:include 引入的支持样式表被锁定,但顶级样式表未被锁定。
我能够通过创建一个新的 MVC 项目并调用以下 GetXslt2FO 方法来重现该问题。在使用 .NET XslCompiledTransform 时,我没有看到这个问题。
如何阻止文件表锁定的发生?
这是我的示例代码:
public XsltExecutable GetExecutable(string stylesheetPath)
{
using (FileStream s = new FileStream(stylesheetPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
compiler.BaseUri = new Uri(stylesheetPath);
var executable = compiler.Compile(s);
return executable;
}
}
public string GetXslt2FO(string xsltFilePath, XDocument xml, Dictionary<string, string> args)
{
// Compile stylesheet
var executable = GetExecutable(xsltFilePath);
var declaredArgs = executable.GetGlobalParameters();
// Do transformation to a destination
var destination = new DomDestination();
using (var inputStream = new MemoryStream())
{
xml.Save(inputStream);
inputStream.Position = 0;
var transformer = executable.Load();
FileInfo stylesheetFileInfo = new FileInfo(xsltFilePath);
transformer.SetInputStream(inputStream, new Uri(stylesheetFileInfo.DirectoryName));
foreach (var arg in args)
{
var matchingArgDeclaration = declaredArgs.FirstOrDefault(a => a.Key.LocalName.ToLower() == arg.Key.ToLower());
if (matchingArgDeclaration.Key == null)
{
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(arg.Value));
}
else
{
// try to load up the specific parameter type
// list is based on http://www.saxonica.com/documentation/#!dotnetdoc/Saxon.Api/XdmAtomicValue
XdmItemType argType = matchingArgDeclaration.Value.getDeclaredItemType();
var argTypeName = "";
if (argType != null &&
argType is XdmAtomicType)
argTypeName = ((XdmAtomicType)argType).Name.LocalName;
switch (argTypeName.ToLower())
{
case "boolean":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToBoolean(arg.Value)));
break;
case "integer":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToInt32(arg.Value)));
break;
case "decimal":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToDecimal(arg.Value)));
break;
case "float":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToSingle(arg.Value)));
break;
case "double":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToDouble(arg.Value)));
break;
case "anyuri":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(new Uri(arg.Value)));
break;
case "qname":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(new QName(arg.Value)));
break;
default:
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(((arg.Value))));
break;
}
}
}
transformer.Run(destination);
}
return destination.XmlDocument.OuterXml;
}
这是一个 Saxon 错误,已在维护版本 9.8.0.2 中修复。感谢您报告。
似乎原生 .NET 版本 SaxonCS (11.3.0) 又锁定了样式表。
我正在使用最新版本的 Saxon HE for .NET (9.7.0.18),我发现我的样式表文件被锁定的问题。这个问题并不总是立即发生,但我通常会在多次调用样式表后开始看到这个问题。到那时,在我回收应用程序池之前,我将无法再通过文本编辑器保存对相关样式表的更改。
据我目前所见,似乎通过 xsl:import 或 xsl:include 引入的支持样式表被锁定,但顶级样式表未被锁定。
我能够通过创建一个新的 MVC 项目并调用以下 GetXslt2FO 方法来重现该问题。在使用 .NET XslCompiledTransform 时,我没有看到这个问题。
如何阻止文件表锁定的发生?
这是我的示例代码:
public XsltExecutable GetExecutable(string stylesheetPath)
{
using (FileStream s = new FileStream(stylesheetPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
compiler.BaseUri = new Uri(stylesheetPath);
var executable = compiler.Compile(s);
return executable;
}
}
public string GetXslt2FO(string xsltFilePath, XDocument xml, Dictionary<string, string> args)
{
// Compile stylesheet
var executable = GetExecutable(xsltFilePath);
var declaredArgs = executable.GetGlobalParameters();
// Do transformation to a destination
var destination = new DomDestination();
using (var inputStream = new MemoryStream())
{
xml.Save(inputStream);
inputStream.Position = 0;
var transformer = executable.Load();
FileInfo stylesheetFileInfo = new FileInfo(xsltFilePath);
transformer.SetInputStream(inputStream, new Uri(stylesheetFileInfo.DirectoryName));
foreach (var arg in args)
{
var matchingArgDeclaration = declaredArgs.FirstOrDefault(a => a.Key.LocalName.ToLower() == arg.Key.ToLower());
if (matchingArgDeclaration.Key == null)
{
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(arg.Value));
}
else
{
// try to load up the specific parameter type
// list is based on http://www.saxonica.com/documentation/#!dotnetdoc/Saxon.Api/XdmAtomicValue
XdmItemType argType = matchingArgDeclaration.Value.getDeclaredItemType();
var argTypeName = "";
if (argType != null &&
argType is XdmAtomicType)
argTypeName = ((XdmAtomicType)argType).Name.LocalName;
switch (argTypeName.ToLower())
{
case "boolean":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToBoolean(arg.Value)));
break;
case "integer":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToInt32(arg.Value)));
break;
case "decimal":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToDecimal(arg.Value)));
break;
case "float":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToSingle(arg.Value)));
break;
case "double":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(Convert.ToDouble(arg.Value)));
break;
case "anyuri":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(new Uri(arg.Value)));
break;
case "qname":
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(new QName(arg.Value)));
break;
default:
transformer.SetParameter(new QName(arg.Key), new XdmAtomicValue(((arg.Value))));
break;
}
}
}
transformer.Run(destination);
}
return destination.XmlDocument.OuterXml;
}
这是一个 Saxon 错误,已在维护版本 9.8.0.2 中修复。感谢您报告。
似乎原生 .NET 版本 SaxonCS (11.3.0) 又锁定了样式表。