C# Saxon中的BaseUri在尝试编译xslt内容时会导致问题

C# Saxon中的BaseUri在尝试编译xslt内容时会导致问题,c#,xml,xslt,uri,saxon,C#,Xml,Xslt,Uri,Saxon,这是我的密码: 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:

这是我的密码:

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:值不能为null。 参数名称:BaseUri 位于Saxon.Api.XsltCompiler.Compile(XmlReader) 在C:\Users\Davíð\source\Saxon\Saxon\Program.cs中的Saxon.Program.TransformData(字符串数据、字符串xmlCopy、字符串xslt)中:第33行 位于C:\Users\Davíð\source\Saxon\Saxon\Program.cs中的Saxon.Program.Main(字符串[]args):第22行


根据以下注释、固定和工作代码:

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
}
您有几个问题:

  • 每次调用时返回一个新的
    XsltCompiler
    。你两次叫它

    processor.NewXsltCompiler().BaseUri = new Uri("C:/Users/Davíð/source/Saxon/Saxon");
    XsltExecutable templates = processor.NewXsltCompiler().Compile(new XmlTextReader(new StringReader(xslt)));
    
    在第一个上设置代码集,然后创建另一个来执行编译。因此,在实际用于执行工作的
    XsltCompiler
    上从未设置
    BaseUri

    这是异常的直接原因未经处理的异常:System.ArgumentNullException:值不能为null。参数名称:Saxon.Api.XsltCompiler.Compile(XmlReader)处的BaseUri

    您应该只创建一个
    XsltCompiler

  • 您使用的是
    XmlTextReader
    ,但已经超过10年了。相反,使用。此外,一定要在事后处理

  • 将文件
    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));
    }
}
您有几个问题:

  • 每次调用时返回一个新的
    XsltCompiler
    。你两次叫它

    processor.NewXsltCompiler().BaseUri = new Uri("C:/Users/Davíð/source/Saxon/Saxon");
    XsltExecutable templates = processor.NewXsltCompiler().Compile(new XmlTextReader(new StringReader(xslt)));
    
    在第一个上设置代码集,然后创建另一个来执行编译。因此,在实际用于执行工作的
    XsltCompiler
    上从未设置
    BaseUri

    这是异常的直接原因未经处理的异常:System.ArgumentNullException:值不能为null。参数名称:Saxon.Api.XsltCompiler.Compile(XmlReader)处的BaseUri

    您应该只创建一个
    XsltCompiler

  • 您使用的是
    XmlTextReader
    ,但已经超过10年了。相反,使用。此外,一定要在事后处理

  • 将文件
    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));
    }
}

请您编辑您的问题,并提供您正在使用的萨克森的确切版本和版本,好吗?堆栈跟踪也会有所帮助。您真的需要像代码那样将XML解析为.NET字符串吗?与使用ReadAllText相比,使用文档生成器从文件/URI简单地构建文档应该更容易、更好地处理不同的编码。相反,使用。另外,请务必在事后处理它。另外,请您的问题包括以下内容:1)异常的完整
ToString()
输出,包括异常类型、消息、回溯和内部异常(如果有)。2) 显示重现该问题的最小示例XML和XSL文件?如果我们能重现您的问题,我们就更有可能解决您的问题。请参阅:、并在每次调用时返回一个新的
XsltCompiler
。调用它两次:首先设置
BaseUri
,然后创建另一个来进行处理。您是否尝试过
var compiler=processor.NewXsltCompiler();compiler.BaseUri=newuri(“C:/Users/Davíð/source/Saxon/Saxon”);var templates=compiler.Compile(/*余数与以前一样…
?顺便说一句,.Net中的字符串是不可变的,因此没有理由像使用
xmlCopy
那样通过读取两次文件来深度克隆字符串。请编辑您的问题并提供您使用的Saxon的确切版本和版本吗?堆栈跟踪也会有所帮助。您真的需要吗要像代码那样将XML解析为.NET字符串?与使用ReadAllText相比,使用文档生成器从文件/URI简单地构建文档应该更容易、更好地处理不同的编码。不知道这是否会导致您的问题,但是,请改为使用。此外,请务必在以后处理它。另外,请您将问题包括在内以下内容:1)异常的完整
ToString()
输出,包括异常类型、消息、回溯和内部异常(如果有)。2)显示重现问题的最小示例XML和XSL文件?如果我们能重现您的问题,我们就更有可能解决您的问题。请参阅:、并在每次调用时返回一个新的
XsltCompiler
。调用它两次:首先设置
BaseUri
,然后创建另一个来进行处理。您是否尝试过
var compiler=processor.NewXsltCompiler();compiler.BaseUri=newuri(“C:/Users/Davíð/source/Saxon/Saxon”);var templates=compiler.Compile(/*余数与以前一样…
?顺便说一句,.Net中的字符串是不可变的,因此没有理由像使用
xmlCopy
那样通过读取文件两次来深度克隆字符串。