使用Saxon-HE 9.9.1.5构建.NET VSTO应用程序。为XSLT 3.0转换器设置全局样式表参数不起作用。我无法通过QName / XdmAtomicValue词典。
相同的XSLT在Java 8中使用Saxon-HE 9.8.0-10可以正常工作。
private Dictionary<QName, XdmValue> createParameters(IDictionary<string, string> properties)
{
Dictionary<QName, XdmValue> retVal = new Dictionary<QName, XdmValue>(properties.Count);
foreach (var kvp in properties)
{
LOGGER.Debug(String.Format("\tName: \"{0}\"; Value: \"{1}\"", kvp.Key, kvp.Value));
retVal.Add(new QName(kvp.Key), new XdmAtomicValue(kvp.Value) );
}
return retVal;
}
public void Transform(FileInfo xmlInput, FileInfo output, IDictionary<string,string> properties )
{
try
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Xslt30Transformer transformer = Executable.Load30();
Serializer serializer = processor.NewSerializer();
FileStream outStream = new FileStream(output.FullName.ToString(), FileMode.Append, FileAccess.Write);
serializer.SetOutputStream(outStream);
FileStream inputStream = new FileStream(xmlInput.FullName.ToString(), FileMode.Open, FileAccess.Read);
Dictionary<QName, XdmValue> parameters = createParameters(properties);
LOGGER.Debug(String.Format("\nInput: \"{0}\"\nOutput: \"{1}\"\nParameters: {2}", xmlInput.FullName, output.FullName, parameters.Count));
transformer.SetStylesheetParameters(parameters);
transformer.ApplyTemplates(inputStream, serializer);
outStream.Flush();
outStream.Close();
inputStream.Close();
stopwatch.Stop();
LOGGER.Debug(String.Format("Generate model call took: {0}", stopwatch.ElapsedMilliseconds));
}
catch ( Exception e)
{
LOGGER.Warn(String.Format("{0} {1}", e.Message, e.StackTrace));
}
}
}
使用全局XSLT默认值代替传递的参数
我已尝试用以下方法重现该问题
static void Main(string[] args)
{
Processor processor = new Processor();
string xslt = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='3.0' xmlns:xs='http://www.w3.org/2001/XMLSchema' exclude-result-prefixes='#all'>
<xsl:param name='p1' as='xs:string'>p1 default</xsl:param>
<xsl:param name='p2' as='xs:string'>p2 default</xsl:param>
<xsl:template match='/' name='xsl:initial-template'>
<xsl:value-of select='$p1, $p2'/>
</xsl:template>
</xsl:stylesheet>";
XsltExecutable xsltExecutable;
using (StringReader sr = new StringReader(xslt))
{
xsltExecutable = processor.NewXsltCompiler().Compile(sr);
}
Xslt30Transformer xslt30Transformer = xsltExecutable.Load30();
xslt30Transformer.CallTemplate(null, processor.NewSerializer(Console.Out));
Console.WriteLine();
xslt30Transformer = xsltExecutable.Load30();
xslt30Transformer.SetStylesheetParameters(new Dictionary<QName, XdmValue>() { { new QName("p2"), new XdmAtomicValue("p2 new value") } });
xslt30Transformer.CallTemplate(null, processor.NewSerializer(Console.Out));
Console.WriteLine();
XdmNode inputNode;
string xml = @"<root><values></values></root>";
DocumentBuilder docBuilder = processor.NewDocumentBuilder();
docBuilder.BaseUri = new Uri("from:string-input");
using (StringReader inputReader = new StringReader(xml))
{
inputNode = docBuilder.Build(inputReader);
}
xslt = @"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='3.0' xmlns:xs='http://www.w3.org/2001/XMLSchema' exclude-result-prefixes='#all'>
<xsl:param name='p1' as='xs:string'>p1 default</xsl:param>
<xsl:param name='p2' as='xs:string'>p2 default</xsl:param>
<xsl:mode on-no-match='shallow-copy'/>
<xsl:template match='values'>
<xsl:value-of select='$p1, $p2'/>
</xsl:template>
</xsl:stylesheet>";
XsltExecutable xsltExecutable2;
using (StringReader sr = new StringReader(xslt))
{
xsltExecutable2 = processor.NewXsltCompiler().Compile(sr);
}
Xslt30Transformer xslt30Transformer2 = xsltExecutable2.Load30();
xslt30Transformer2.ApplyTemplates(inputNode, processor.NewSerializer(Console.Out));
Console.WriteLine();
xslt30Transformer2 = xsltExecutable2.Load30();
xslt30Transformer2.SetStylesheetParameters(new Dictionary<QName, XdmValue>() { { new QName("p2"), new XdmAtomicValue("p2 new value") } });
xslt30Transformer2.ApplyTemplates(inputNode, processor.NewSerializer(Console.Out));
Console.WriteLine();
}
但是我用Saxon 9.9.1.5获得的输出是
<?xml version="1.0" encoding="UTF-8"?>p1 default p2 default
<?xml version="1.0" encoding="UTF-8"?>p1 default p2 new value
<?xml version="1.0" encoding="UTF-8"?><root>p1 default p2 default</root>
<?xml version="1.0" encoding="UTF-8"?><root>p1 default p2 new value</root>
考虑提供最少的XML,XSLT和C#示例,并提供您获得的输出,以便我们识别问题所在。