Bug #4088
closedSerialization with ResultDocumentHandler doesn't take output properties defined with "format" attribute and "xsl:output" or directly as attributes of "xsl:result-document" into account
100%
Description
This is related to https://saxonica.plan.io/issues/4087 but I file this as a separate issue as I am now convinced this is a bug (various samples run fine when used with Java, both from the command line and the API, and with .NET from the command line and the API without using ResultDocumentHandler but fail with ResultDocumentHandler):
It seems Saxon .NET's XsltTransformer
, when using an assigned ResultDocumentHandler
, doesn't take any serialization properties of the xsl:result-document
into account, neither those defined in a named xsl:output
referenced with the format
attribute nor those specified directly like e.g. method="json"
, instead it looks like a default XML serialization is used in all cases.
That means any attempt to use e.g. method="json"
with maps or arrays fails with "SENR0001: Cannot serialize a map using the xml method".
Example XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="html" indent="yes" html-version="5"/>
<xsl:template match="/" name="xsl:initial-template">
<html>
<head>
<title>Test</title>
</head>
<body>
<h1>Test</h1>
</body>
</html>
<xsl:result-document href="result-1.json" method="json" indent="yes">
<xsl:sequence select="map { 'name' : 'foo', 'values' : [ 'a', 'b', 'c' ] }"/>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
C#
static void Main(string[] args)
{
TestXsltFromURL(Path.Combine(Directory.GetCurrentDirectory(), "output-method-json-test1.xsl"));
}
static void TestXsltFromURL(string xslURL)
{
Processor proc = new Processor(false);
XsltTransformer transformer = proc.NewXsltCompiler().Compile(new Uri(xslURL)).Load();
transformer.InitialTemplate = new QName("http://www.w3.org/1999/XSL/Transform", "initial-template");
transformer.Run(proc.NewSerializer(Console.Out));
Console.WriteLine();
MyResultDocumentHandler resDocHandler = new MyResultDocumentHandler(proc);
transformer.ResultDocumentHandler = resDocHandler;
transformer.Run(proc.NewSerializer(Console.Out));
foreach (MySerializer ser in resDocHandler.Serializers)
{
Console.WriteLine("{0}:\n{1}", ser.Href, ser.Result);
Console.WriteLine();
}
}
gives
Error at char 6 in xsl:sequence/@select on line 20 column 84 of output-method-json-test1.xsl:
SENR0001: Cannot serialize a map using the xml method
Saxon.Api.DynamicError
HResult=0x80131500
Message=Cannot serialize a map using the xml method
Source=saxon9he-api
StackTrace:
at Saxon.Api.XsltTransformer.Run(XmlDestination destination)
at ResultDocDocTypeMissing.Program.TestXsltFromURL(String xslURL) in C:\SomePath\ResultDocDocTypeMissing\ResultDocDocTypeMissing\Program.cs:line 34
at ResultDocDocTypeMissing.Program.Main(String[] args) in C:\SomePath\ResultDocDocTypeMissing\ResultDocDocTypeMissing\Program.cs:line 15
Line 34 is the second transformer.Run(proc.NewSerializer(Console.Out));
call, after the transformer.ResultDocumentHandler = resDocHandler;
has been set.
Used classes are:
internal class MyResultDocumentHandler : IResultDocumentHandler
{
private Processor proc;
public List<MySerializer> Serializers { get; set; }
public MyResultDocumentHandler(Processor proc)
{
this.proc = proc;
Serializers = new List<MySerializer>();
}
public XmlDestination HandleResultDocument(string href, Uri baseUri)
{
var ser = new MySerializer(proc, href);
Serializers.Add(ser);
return ser;
}
}
internal class MySerializer : Serializer
{
private StringWriter resultWriter;
public string Result { get; private set; }
public string Href { get; }
public MySerializer(Processor processor, string href)
{
SetProcessor(processor);
Href = href;
resultWriter = new StringWriter();
SetOutputWriter(resultWriter);
}
public override void Close()
{
Result = resultWriter.ToString();
resultWriter.Close();
resultWriter.Dispose();
base.Close();
}
}
Updated by O'Neil Delpratt over 5 years ago
Yes this is a bug. I have managed to reproduce the error message.
Updated by O'Neil Delpratt over 5 years ago
There ha been significant changes to the XmlDestination and how we manage the sub-classes such as the Serializer in Saxon 9.9. These changes we hope are not too disruptive for users.
Updated by Martin Honnen over 5 years ago
As I am not getting anywhere trying to use Saxon 9.8 .NET and XsltTransformer and ResultDocumentHandler to handle xsl:result-document
I will probably have to wait for the 9.9 release. Is there any date on the release or if the public APIs are at least already stable is there any chance to get the API doc of 9.9 online? Will Xslt30Transformer in 9.9 provide a way to handle xsl:result-document
so that it is no longer necessary to rely on XsltTransformer for that?
Updated by O'Neil Delpratt over 5 years ago
- Status changed from New to In Progress
- Applies to branch 9.9 added
Update,
The only difference on the Saxon 9.9 is that the Serializer can only be created via the Processor. This is now inline with how it is done on the Java platform. I can confirm that we are getting the same error on Saxon 9.9 for .NET. Investigating the problem further.
Updated by O'Neil Delpratt over 5 years ago
The issue is the handling of ResultDocuments on .NET relies on IResultDocumentHandler interface, which works with a OutputURIResolver class on Java. The OutputURIResolver interface from Saxon 9.9 is obsolescent. It is unable to handle the full flexibility of XSLT 3.0, for example it cannot handle raw output, JSON serialization, or the item-separator serialization property.
I will look to port the new mechanism on Java to .NET.
Updated by O'Neil Delpratt over 5 years ago
- Status changed from In Progress to Resolved
- Fix Committed on Branch 9.9 added
Bug fixed on the Saxon 9.9 branch.
Updated by O'Neil Delpratt over 5 years ago
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.9.1.1 added
Bug fix applied to the Saxon 9.9.1.1 maintenance release.
Updated by O'Neil Delpratt over 5 years ago
- Status changed from Resolved to Closed
Please register to edit this issue