首页 > 解决方案 > 使用 Saxon 进行 Xslt2.0 转换的序列化程序问题

问题描述

这是我第一次尝试在 C# 中使用 SaxonHE 9.9 编写 Xslt2.0 转换,所以这里的问题是当我创建序列化程序时,我收到错误,即不class Saxon.Api.Serializer包含具有 0 个参数的构造函数。

我知道这个错误是什么意思,但不知道为什么会发生,因为我看到的每个示例都会创建这样的序列化程序。这个问题听起来有点愚蠢,但我找不到让它工作的答案。

using Saxon.Api;

namespace XY
{
    class Program
    {
        static void Main(string[] args)
        {            
            String SourceFilename = "./test/test.xml";
            String StylesheetFilename = "./scripte/xml-to-html.xsl";
            String OutputFilename = "./Output/test.html";

            using (FileStream streamXml = File.OpenRead(SourceFilename))
            {
                using (FileStream streamXsl = File.OpenRead(StylesheetFilename))
                {
                    Processor processor = new Processor();

                    DocumentBuilder builder = processor.NewDocumentBuilder();
                    Uri uri = new Uri("urn:test");
                    builder.BaseUri = uri;

                    XdmNode input = builder.Build(streamXml);
                    XsltTransformer transformer = processor.NewXsltCompiler().Compile(streamXsl).Load();

                    transformer.InitialContextNode = input;

                    Serializer serializer = new Serializer();
                    serializer.SetOutputFile(OutputFilename);
                    transformer.Run(serializer);
                }
            }

            Console.WriteLine("test.html created successfully");
        }
    }
}

编辑

using System;
using Saxon.Api;
using System.IO;
using System.Reflection;

namespace XY
{
    class Program
    {
        static void Main(string[] args)
        {
            string currentDirectory = Directory.GetCurrentDirectory();

            String SourceFilename = ".\\test\\test.xml";
            String StylesheetFilename = ".\\scripte\\xml-to-html.xsl";
            String OutputFilename = ".\\Output\\result.html";

            if (StylesheetFilename.StartsWith(".\\"))
            {
                StylesheetFilename = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + StylesheetFilename;
            }

            if (SourceFilename.StartsWith(".\\"))
            {
                SourceFilename = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\" + SourceFilename;
            }

            var uri_source = new System.Uri(SourceFilename);
            var uri_xsl = new System.Uri(StylesheetFilename);


            Processor processor = new Processor();

            XdmNode input = processor.NewDocumentBuilder().Build(uri_source);

            processor.SetProperty("http://saxon.sf.net/feature/preferJaxpParser", "true");

            XsltCompiler compiler = processor.NewXsltCompiler();

            XsltExecutable executable = compiler.Compile(uri_xsl);

            XsltTransformer transformer = executable.Load();

            transformer.InitialContextNode = input;

            Serializer serializer = processor.NewSerializer();

            System.IO.StreamWriter stream = new StreamWriter(OutputFilename);

            serializer.SetOutputWriter(stream);

            transformer.Run(serializer);

            stream.Close();
        }
    }
}

我也改变了一些其他的想法,现在它可以工作了,谢谢你的回答。

标签: c#xslt-2.0saxon

解决方案


我将记录一个错误,即存在使用“new Serializer()”表单的示例应用程序和/或文档。

我们在 9.8 中从 Java 产品中删除了它,因为它经常导致 Serializer 无法(必须)访问所有配置选项(保存在处理器中);还使用工厂方法Processor.newSerializer()可能允许我们创建 的子类Serializer,因此它更加灵活。然后,我们在 9.9 版本中在 .NET 上遵循了这种模式,部分原因是相同的,部分原因是 .NET API 现在已被重写为 Java API 之上的一个非常薄的层,这有助于我们保持通用性,并且简化测试。

我们努力保持主要产品 API 的向后兼容性,但这不是覆盖所有其他要求的要求;如果我们觉得我们遇到了严重错误,那么我们就修复它。正如有人为政策辩护所说的那样,“未来比过去更长”。

之后

我们做了一些检查,我们认为 9.9 文档和示例应用程序是正确的;您必须使用旧版本。如果我错了,请指出您发现错误信息的具体位置。


推荐阅读