BaseUri в Saxon вызывает проблемы при попытке компилировать содержимое xslt - PullRequest
0 голосов
/ 10 октября 2019

Вот мой код:

static void Main(string[] args)
{
    string xml = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/data.xml");
    string xslt = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/dataXslt.xsl");
    string xmlCopy = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/data.xml");

    TransformData(xml, xmlCopy, xslt);
}

static public void TransformData(string data, string xmlCopy, string xslt)
{
    // Create a Processor instance.
    Processor processor = new Processor();

    // Create a compiled stylesheet
    processor.NewXsltCompiler().BaseUri = new Uri("C:/Users/Davíð/source/Saxon/Saxon");
    XsltExecutable templates = processor.NewXsltCompiler().Compile(new XmlTextReader(new StringReader(xslt)));

    // Note: we could actually use the same Xslt30Transformer in this case.
    // But in principle, the two transformations could be done in parallel in separate threads.

    // Do the first transformation
    Console.WriteLine("\n\n----- transform of " + data + " -----");
    Xslt30Transformer transformer1 = templates.Load30();
    XdmNode input1 = processor.NewDocumentBuilder().Build(new XmlTextReader(new StringReader(data)));
    transformer1.ApplyTemplates(input1, processor.NewSerializer(Console.Out));     // default destination is Console.Out

    // Do the second transformation
    Console.WriteLine("\n\n----- transform of " + xmlCopy + " -----");
    Xslt30Transformer transformer2 = templates.Load30();
    XdmNode input2 = processor.NewDocumentBuilder().Build(new XmlTextReader(new StringReader(xmlCopy)));
    transformer2.ApplyTemplates(input2, processor.NewSerializer(Console.Out));     // default destination is Console.Out
}

Вот ошибка, которую я получаю, независимо от того, удаляю ли я BaseUri или нет.

Необработанное исключение: System.ArgumentNullException: значение не можетбыть нулевымИмя параметра: BaseUri в Saxon.Api.XsltCompiler.Compile (читатель XmlReader) в Saxon.Program.TransformData (Строковые данные, Строка xmlCopy, Строка xslt) в C: \ Users \ Davíð \ source \ Saxon \ Saxon \ Program.cs:строка 33 в Saxon.Program.Main (String [] args) в C: \ Users \ Davíð \ source \ Saxon \ Saxon \ Program.cs: строка 22 * ​​1007 *


На основе комментариев,исправленный и рабочий код ниже:

static void Main(string[] args)

{
    string xml = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/data.xml");
    string xslt = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/dataXslt.xsl");

    TransformData(xml, xml, xslt);
}

static public void TransformData(string data, string xmlCopy, string xslt)
{
    // Create a Processor instance.
    Processor processor = new Processor();

    // Create a compiled stylesheet
    var compiler = processor.NewXsltCompiler();
    compiler.BaseUri = new Uri("C:/Users/Davíð/source/Saxon/Saxon");
    XsltExecutable templates = compiler.Compile(XmlReader.Create(new StringReader(xslt)));

    // Note: we could actually use the same Xslt30Transformer in this case.
    // But in principle, the two transformations could be done in parallel in separate threads.

    // Do the first transformation
    Console.WriteLine("\n\n----- transform of " + data + " -----");
    Xslt30Transformer transformer1 = templates.Load30();
    XdmNode input1 = processor.NewDocumentBuilder().Build(XmlReader.Create(new StringReader(data)));
    transformer1.ApplyTemplates(input1, processor.NewSerializer(Console.Out));     // default destination is Console.Out

    // Do the second transformation
    Console.WriteLine("\n\n----- transform of " + xmlCopy + " -----");
    Xslt30Transformer transformer2 = templates.Load30();
    XdmNode input2 = processor.NewDocumentBuilder().Build(new XmlTextReader(new StringReader(xmlCopy)));
    transformer2.ApplyTemplates(input2, processor.NewSerializer(Console.Out));     // default destination is Console.Out
}

1 Ответ

0 голосов
/ 14 октября 2019

У вас есть несколько проблем:

  • processor.NewXsltCompiler() возвращает новый XsltCompiler при каждом вызове. Вы называете это дважды :

    processor.NewXsltCompiler().BaseUri = new Uri("C:/Users/Davíð/source/Saxon/Saxon");
    XsltExecutable templates = processor.NewXsltCompiler().Compile(new XmlTextReader(new StringReader(xslt)));
    

    Код устанавливает BaseUri на первом, а затем создает другой для компиляции. Таким образом, BaseUri никогда не устанавливается на XsltCompiler, который фактически используется для выполнения работы.

    Это непосредственная причина исключения Необработанное исключение: System.ArgumentNullException: значение не может быть нулевым. Имя параметра: BaseUri в Saxon.Api.XsltCompiler.Compile (читатель XmlReader) .

    Вместо этого вы должны создать только один XsltCompiler.

  • Вы используете XmlTextReader, но XmlTextReader устарело с .Net 2.0 более 10 лет назад. Вместо этого используйте XmlReader.Create(TextReader). Кроме того, обязательно утилизируйте его после этого.

  • Две копии содержимого файла data.xml загружаются в память, в строки xml и xmlCopy. Но строки в .Net являются неизменяемыми, поэтому в этом нет необходимости.

Таким образом, ваш код должен выглядеть примерно так:

public static void Main(string[] args)
{
    string xml = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/data.xml");
    string xslt = File.ReadAllText("C:/Users/Davíð/source/Saxon/Saxon/dataXslt.xsl");

    TransformData(xml, xml, xslt);
}

static public void TransformData(string xml1, string xml2, string xslt)
{
    // Create a Processor instance.
    var processor = new Processor();

    // Create a compiled stylesheet
    var compiler = processor.NewXsltCompiler();
    compiler.BaseUri = new Uri("C:/Users/Davíð/source/Saxon/Saxon");
    XsltExecutable templates;
    using (var reader = XmlReader.Create(new StringReader(xslt)))
        templates = compiler.Compile(reader);

    // Note: we could actually use the same Xslt30Transformer in this case.
    // But in principle, the two transformations could be done in parallel in separate threads.

    // Do the first transformation
    Console.WriteLine("\n\n----- transform of " + xml1 + " -----");
    TransformData(processor, templates, xml1, Console.Out);

    // Do the second transformation
    Console.WriteLine("\n\n----- transform of " + xml2 + " -----");
    TransformData(processor, templates, xml2, Console.Out);
}

private static void TransformData(Processor processor, XsltExecutable templates, string xml, TextWriter output)
{
    var transformer = templates.Load30();
    using (var reader = XmlReader.Create(new StringReader(xml)))
    {
        var input = processor.NewDocumentBuilder().Build(reader);
        transformer.ApplyTemplates(input, processor.NewSerializer(output));
    }
}
...