用于使用Saxon进行Xslt2.0转换的序列化器的问题

时间:2019-03-05 21:46:08

标签: c# xslt-2.0 saxon

这是我第一次尝试在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();
        }
    }
}

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

3 个答案:

答案 0 :(得分:0)

在9.9中,您可以(或确实需要)创建带有Serializer各种重载的processor.NewSerializer(请参阅http://saxonica.com/html/documentation/dotnetdoc/Saxon/Api/Processor.html#NewSerializer(Stream))。.

答案 1 :(得分:0)

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

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

我们尽力在主要产品API中保持向后兼容性,但这不是覆盖所有其他API的要求;如果我们觉得自己有严重的错误,那么我们将其修复。就像有人说要为该政策辩护,“未来比过去更长”。

LATER

我们进行了一些检查,我们认为9.9文档和样本应用程序正确无误;您必须使用旧版本。如果我记错了,请指明发现错误信息的特定位置。

答案 2 :(得分:0)

这是我解决该问题的方法:

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

namespace Project1
{
    public static class ClassMain
    {
        public static string TransformXml(string xmlData, string xslData)
        {
            var xsltProcessor = new Processor();
            var documentBuilder = xsltProcessor.NewDocumentBuilder();
            documentBuilder.BaseUri = new Uri("file://");
            var xdmNode = documentBuilder.Build(new StringReader(xmlData));

            var xsltCompiler = xsltProcessor.NewXsltCompiler();
            var xsltExecutable = xsltCompiler.Compile(new StringReader(xslData));
            var xsltTransformer = xsltExecutable.Load();
            xsltTransformer.InitialContextNode = xdmNode;

            var results = new XdmDestination();

            xsltTransformer.Run(results);
            return results.XdmNode.OuterXml;
        }

        public static void Main()
        {
            var xmlData = File.ReadAllText("a.xml");
            var xslData = File.ReadAllText("a.xsl");

            var data = TransformXml(xmlData, xslData);
            Console.WriteLine(data);
            Console.ReadKey();
        }
    }
}