Scott
Scott

Reputation: 1253

How Do I Stop Stylesheet File Locking When Using Saxon?

I am using the latest version of Saxon HE for .NET (9.7.0.18) and am seeing issues with my stylesheet files getting locked. The issue does not always occur immediately, but I will generally start to see the issue after several calls to the stylesheet. At that point, I will no longer be able to save changes to the stylesheet in question via a text editor until I recycle the application pool.

From what I am seeing so far, it appears that supporting stylesheets pulled in via xsl:import or xsl:include get locked, but top level stylesheets do not get locked.

I am able to reproduce the issue by creating a new MVC project and calling the following GetXslt2FO method. I do not see this issue when working with .NET XslCompiledTransform.

How can I stop the filesheet locks from occurring?

Here is my example code:

    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;
    }

Upvotes: 1

Views: 123

Answers (2)

M T
M T

Reputation: 1

It seems that the native .NET version SaxonCS (11.3.0) is locking the stylesheets again.

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163322

This was a Saxon bug and is fixed in maintenance release 9.8.0.2. Thank you for reporting it.

Upvotes: 1

Related Questions