Bug #6036


Undeclaration of default namespace is not reported to a SAXResult

Added by Radu Coravu 7 months ago. Updated 3 months ago.

Start date:
Due date:
% Done:


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


I need some advice, the problem might be on our side though... I have this XML:

<?xml version="1.0" encoding="UTF-8"?>

and this XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="" version="3.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <svg xmlns="">
    <xsl:template match="colors/*">
        <circle cx="{(position() - 1) * 100}" cy="100" r="{.}"/>

For the Oxygen debugger we serialize the XML using the net.sf.saxon.event.ComplexContentOutputter class with a serializer. The resulting output is this one:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="">
   <circle cx="100" cy="100" r="10"/>
   <circle cx="300" cy="100" r="20"/>
   <circle cx="500" cy="100" r="15"/>

which is incorrect because the "circle" element should have an empty xmlns="" set on it.

Lookin at the callbacks we receive in our content handler, we do not receive a startPrefixMapping("", "") before the startElement("circle") is received.

Looking at the code here: net.sf.saxon.event.ComplexContentOutputter.startContent() it does something like this:

        if (pendingStartTag.hasURI("") && !pendingNSMap.getDefaultNamespace().isEmpty()) {
            pendingNSMap = pendingNSMap.remove("");

but I'm not sure it is to blame for the problem.

Actions #1

Updated by Michael Kay 7 months ago

I've reproduced this with a unit test (SAXTest.testSAXResult) that runs the transformation using JAXP and sends the output to a SAXResult. If we send the output to a serializer, it's fine, but if we send it to a SAXResult, the startPrefixMapping() call is missing.

The NamespaceMap objects being passed to the startElement calls in the ContentHandlerProxy are fine, but the ContentHandlerProxy seems to be making no serious attempt to determine how the current namespace map differs from the one on the parent element, which is needed to generate the startPrefixMapping events.

It actually appears to call startPrefixMapping() for all in-scope namespaces on the child element, whether or not they were present on the parent; and it doesn't detect the need to issue an undeclaration event because the namespaceMap on the child element contains no evidence that it is needed. This requires comparison with the parent namespace map.

Actions #2

Updated by Michael Kay 7 months ago

  • Tracker changed from Support to Bug
  • Subject changed from Empty namespace not getting serialized to Undeclaration of default namespace is not reported to a SAXResult
  • Category set to JAXP Java API
  • Status changed from New to In Progress
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
Actions #3

Updated by Michael Kay 7 months ago

The way we handle this for the XML serializer is that we put a NamespaceDifferencer in the output pipeline. This handles the maintenance of the namespace stack and passes a NamespaceMap containing only the differences to the next step in the pipeline. We should do the same thing for the SAX output pipeline.

This can be achieved in SAXDestination.getReceiver().

This seems to be sufficient to make the test work, but I think we can do some further tidying up in the ContentHandlerProxy.

Moreover, we need to look at other places where we create a ContentHandlerProxy. Since this is supposed to bridge between Saxon's Receiver events and SAX push events, I would think we need the namespace differencing whenever we do this, and this certainly isn't happening at the moment: there are five places we create a ContentHandlerProxy.

Actions #4

Updated by Michael Kay 7 months ago

  • Status changed from In Progress to Resolved
  • Applies to branch 11, 12, trunk added
  • Fix Committed on Branch 11, 12, trunk added
  • Platforms Java added

On the 12.x and main branches I reviewed all uses of ContentHandlerProxy to add a NamespaceDifferencer in front of them.

On the 11.x branch I only changed the one that caused the failure, in SAXDestination.getReceiver().

Actions #5

Updated by Radu Coravu 7 months ago

Thanks Michael for investigating this, I will try to identify your changes and see if we can make a patch on our side for a minor Oxygen 25.1 bug fix release. We plan to maybe look into upgrading Oxygen to using Saxon 12 in Autumn this year for version 26 if time allows.

Actions #6

Updated by O'Neil Delpratt 5 months ago

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

Bug fix applied in the Saxon 12.3 maintenance release.

Actions #7

Updated by O'Neil Delpratt 5 months ago

  • Status changed from Closed to Resolved

Leaving this bug issue as resolved until resolved against Saxon 11.

Actions #8

Updated by Debbie Lockett 3 months ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 11.6 added

Bug fix applied in the Saxon 11.6 maintenance release.

Please register to edit this issue

Also available in: Atom PDF