Bug #6669
closedValidated result with mixed content is indented
0%
Description
On Slack I found that Saxon (EE 12.5) indents the output of the following XSLT 3 using schema-aware processing:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
<xsl:import-schema>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="letterBody">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="salutation">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="quantity" type="xsd:positiveInteger"/>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</xsl:import-schema>
<xsl:param name="indent" static="yes" as="xsd:boolean" select="true()"/>
<xsl:output _indent="{$indent}"/>
<xsl:template name="xsl:initial-template">
<xsl:document validation="strict"><letterBody><salutation>Dear Mr.<name>Robert Smith</name>.</salutation> Your order of <quantity>1</quantity><productName>Baby Monitor</productName> shipped from our warehouse on <shipDate>1999-05-21</shipDate>.</letterBody></xsl:document>
</xsl:template>
</xsl:stylesheet>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<letterBody>
<salutation>Dear Mr.<name>Robert Smith</name>.</salutation> Your order of <quantity>1</quantity>
<productName>Baby Monitor</productName> shipped from our warehouse on <shipDate>1999-05-21</shipDate>.</letterBody>
It seems the mixed complex types should prevent Saxon from indenting the result.
Updated by Michael Kay 4 days ago
It seems the problem here is not with the serialization, but with the validation: the outermost element is entering the serialization pipeline with a type annotation of xs:untyped
.
There seem to be two things going on here. Firstly, the xsl:document
instruction is being evaluated in pull rather than push mode, which means that it builds a tree in memory rather than piping straight through to the serializer. For some reason the push mode code is commented out. Secondly, the pull-mode code isn't validating the top level element correctly.
Updated by Michael Kay 4 days ago
The problem goes away if you specify method="xml"
on the xsl:output declaration.
Because there is no explicit method, the serialization pipeline has to include an extra step (called an UncommittedSerializer
) which decides what method to use based on the name of the first startElement event. The UncommittedSerializer appears to be losing the type annotation on the element node, which means that the serializer is treating the outermost element as untyped, and not as mixed content.
Updated by Michael Kay 4 days ago
I think the problem is at UncommittedSerializer line 207, where it does
((NodeInfo) item).copy(this, CopyOptions.ALL_NAMESPACES, locationId);
The second argument should set the option CopyOptions.TYPE_ANNOTATIONS
. Failure to set this means that the type annotation isn't passed on down the pipeline.
Updated by Michael Kay 4 days ago
Created xslt40 test case output-0729 (though this isn't specific to XSLT 4).
Test passes with this change.
But I still want to explore: why is the xsl:document instruction evaluated in pull mode, rather than pushing output straight into the serializer?
Updated by Michael Kay 4 days ago
xsl:document
was using push mode when non-validating, but I have now changed it to do so also when validating.`
Updated by Michael Kay about 12 hours ago
- Status changed from New to Resolved
- Applies to branch 11, trunk added
- Fix Committed on Branch 12, trunk added
Please register to edit this issue