使用 Saxon 时如何停止样式表文件锁定?

Posted

技术标签:

【中文标题】使用 Saxon 时如何停止样式表文件锁定?【英文标题】:How Do I Stop Stylesheet File Locking When Using Saxon? 【发布时间】:2017-11-15 10:42:05 【问题描述】:

我正在使用最新版本的 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;
    

【问题讨论】:

我在这里提出了一个撒克逊问题:请跟踪它:saxonica.plan.io/issues/3275 您能否更准确地了解症状 - 是什么告诉您文件已被锁定? 我更新了我的问题详情。一旦文件被锁定,我就不能再通过文本编辑器保存对它的更改。 我们已经重现了错误问题并解决了它。该补丁将在 Saxon 9.7 的下一个维护版本中提供。请注意,Saxon 9.8 中不存在该错误,因此可能值得升级。 感谢您的帮助。我只是在看 Nuget 上可用的内容,所以我没有意识到有 9.8 版本。我现在在Saxon SourceForge site 上看到了更新的版本。 【参考方案1】:

这是撒克逊人的错误,已在维护版本 9.8.0.2 中修复。感谢您的报告。

【讨论】:

以上是关于使用 Saxon 时如何停止样式表文件锁定?的主要内容,如果未能解决你的问题,请参考以下文章

编译样式表时的未知函数 saxon:parse-html

释放文件锁时如何通知另一个进程?

如何将xsl文件转换为sef文件

ORACLE 如何查询被锁定表及如何解锁释放session

如何使用 Yarn 基于锁文件安装软件包?

如何使用 File#flock 对独占锁发出非阻塞请求?