Maintenance. Planio will be undergoing a scheduled maintenance this weekend. Between Saturday, July 24 at 9:00 UTC and Sunday, July 25, 22:00 UTC your account might observe occasional downtimes which may last up to several minutes in some cases.

Bug #4699

Copy empty attribute using xsl:where-populated

Added by Johan Gheys 11 months ago. Updated 9 months ago.

XSLT conformance
Start date:
Due date:
% Done:


Estimated time:
Legacy ID:
Applies to branch:
10, trunk
Fix Committed on Branch:
10, trunk
Fixed in Maintenance Release:


Since version 10.0 the performance of some of our xslt's has decreased due to the removal of the "bulk" and "grafting" copying capabilities. To remedy this, we are more and more using maps. When reworking one of our xslt's, we notice that an empty attribute (with string-length() = 0) does not always appear in the (secondary) output file.

The uploaded zip file contains all necessary files to reproduce the problem with Saxon-EE 10.2.

The problem does not occur with Saxon-EE (56 KB) Johan Gheys, 2020-08-28 20:49


#1 Updated by Michael Kay 11 months ago

Confirmed that with 9.9, the expected name="" attribute is present on line 400 of the output, and with 10.2 it is absent; and that there are other similar differences in the output files. Which suggests, prima facie, that one of the releases is wrong (unless of course it turns out that the code is dependent on something that's not well-defined, like order of attributes).

This is a complex stylesheet and working out what it does, and where the difference arises, is a pretty large undertaking. Is there any chance of trying to reduce it to a simpler repro? Without having any idea what the data means or how it is being processed, this is quite hard to do. As I mention, there are legitimate reasons why two different processors can give different output.

#2 Updated by Michael Kay 11 months ago

The stylesheet is using the xsl:where-populated instruction, and the implementation of this instruction changed in 10.0 so it has both pull-mode and push-mode implementations (in 9.9 it was always pull mode). Since the semantics of xsl:where-populated examine whether an attribute value is zero-length, this certainly seems like an area to investigate.

#3 Updated by Michael Kay 11 months ago

Confirmed that in 10.2 the WherePopulatedOutputter is suppressing the copying of an empty name attribute. Now we need to work out whether it is correct to do so...

#4 Updated by Michael Kay 11 months ago

No, the logic of WherePopulatedOutputter.attribute() is wrong. It should only suppress an empty attribute when level==0, that is, when an instruction in the sequence constructor contained within xsl:where-populated directly delivers a parentless attribute node. It should not suppress empty attributes deeper in the tree.

#5 Updated by Michael Kay 11 months ago

  • Category set to XSLT conformance
  • Status changed from New to In Progress
  • Assignee set to Michael Kay
  • Applies to branch 10, trunk added

This change fixes the problem. Leaving open for now until the fix is applied to all relevant branches and a regression test is created.

#6 Updated by Michael Kay 11 months ago

  • Subject changed from Copy empty attribute nok to Copy empty attribute using xsl:where-populated

Added XSLT3 test case where-populated/coco-023

#7 Updated by Johan Gheys 11 months ago

I was no longer online yesterday, but apparently - despite the somewhat complex xslt - you were able to find the cause. Thanks for the quick result!

#8 Updated by Michael Kay 11 months ago

  • Status changed from In Progress to Resolved
  • Fix Committed on Branch 10, trunk added

#9 Updated by O'Neil Delpratt 9 months ago

Bug fix applied in the Saxon 10.3 maintenance release

#10 Updated by O'Neil Delpratt 9 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 10.3 added

Please register to edit this issue

Also available in: Atom PDF