Project

Profile

Help

Bug #5196

closed

Missing default namespace attribute on transform to DOM

Added by Mário Martinho Dias almost 3 years ago. Updated almost 3 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
DOM Interface
Sprint/Milestone:
-
Start date:
2022-01-03
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
10, 11, trunk
Fix Committed on Branch:
10, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

There seems to be an issue with Java Saxon-HE 10 when handling default namespace declarations in some circumstances when transforming to DOM, the attribute is missing from the actual model.

TransformerFactory transformerFactory = new net.sf.saxon.TransformerFactoryImpl();
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newDefaultInstance();
documentFactory.setNamespaceAware(true);

Document document = documentFactory.newDocumentBuilder().newDocument();
DOMResult result = new DOMResult(document);

String xml =
		  "<X xmlns=\"FOO\" xmlns:b=\"BAR\">"
		  + "<Y xmlns=\"\"/>"
		+ "</X>";

transformerFactory.newTransformer().transform(new StreamSource(
		new StringReader(xml)), result);
// X/Y@xmlns
assertNotNull(document.getDocumentElement().getChildNodes().item(0)
		.getAttributes().getNamedItem("xmlns"));

This was the specific behavior that I caught, latest 9.9 and 10.0 pass this test, 10.1 onwards doesn't.

If I remove both namespace declarations from "X" it also fails in version 10.0.


Files

saxon-test.zip (2.88 KB) saxon-test.zip testcase Mário Martinho Dias, 2022-01-03 15:15
Actions #1

Updated by Martin Honnen almost 3 years ago

I think the DOM Level 3 spec expects you to call e.g. document.normalizeDocument() to have any namespace declaration attributes in place if the tree is not created by parsing a source document. So if you call that then I think afterwards the assert passes. Let's see what Michael says.

Actions #2

Updated by Michael Kay almost 3 years ago

Added unit test jaxptest/DOMUnitTests/TestIdentityTransformToDomNamespaces.

The problem seems to be in method NamespaceMap.getDifferences() when determining the namespace attributes that need to be added to the Y element; for some reason it's not recognising the need to add a namespace undeclaration for the default namespace. There's another very similar unit test that works successfully, I haven't yet determined why one works and the other fails.

Actions #3

Updated by Michael Kay almost 3 years ago

As regards Martin's comments, Saxon does attempt to create a DOM in which all the necessary namespace declarations are properly represented as attributes -- following the Namespaces 1.0 model as distinct from Namespaces 1.1 (so undeclarations are added only for the default namespace). There are complications if your DOMResult identifies an element node in an existing DOM, but that's not an issue here.

Actions #4

Updated by Michael Kay almost 3 years ago

While on the subject, I added another unit test that demonstrates the requirement to undeclare a namespace that's present in the supplied DOMResult:

        InputSource stub = new InputSource(new StringReader("<a xmlns='http://ns.one/'/>"));
        Document document = documentFactory.newDocumentBuilder().parse(stub);
        DOMResult result = new DOMResult(document.getDocumentElement());

        String xml =  "<X xmlns=''/>";
        transformerFactory.newTransformer().transform(new StreamSource(
                new StringReader(xml)), result);

Saxon currently makes no attempt to handle this case.

Actions #5

Updated by Michael Kay almost 3 years ago

For the first problem, the code at NamespaceMap.getDifferences() # 506 needs to change from

                    // prefix present in other map, absent from this: maybe add an undeclaration
                    if (addUndeclarations || prefixes[i].isEmpty()) {
                        result.add(new NamespaceBinding(other.prefixes[j], ""));
                    }

to

                    // prefix present in other map, absent from this: maybe add an undeclaration
                    if (addUndeclarations || other.prefixes[i].isEmpty()) {
                        result.add(new NamespaceBinding(other.prefixes[j], ""));
                    }
Actions #6

Updated by Michael Kay almost 3 years ago

For the second problem, in DOMWriter, we need to initialise the first entry on the stack of namespace maps to the set of in-scope namespaces on the element node that we are attaching to.

There is code in DOMNodeWrapper.getAllNamespaces() to achieve this, but it's not that easy to deal with its dependencies, so I think that it probably needs to be a cut-and-paste job.

Actions #7

Updated by Michael Kay almost 3 years ago

Note that the representation of namespaces was completely changed in 10.0, and a number of bugs resulted, which probably accounts for the differences between maintenance releases. See bug #4509, bug #4858, bug #4937.

Actions #8

Updated by Michael Kay almost 3 years ago

The test for the second problem (handling existing namespaces in the "stub" to which we are appending) was succeeding spuriously, because I took a short-cut by writing the assertion against the serialization of the resulting DOM. That's not a good enough test, because serialization of the DOM tidies up a lot of mess. We need to test the actual namespace attributes present in the DOM tree (and to do it "the hard way" using the DOM API, not by using XPath).

Actions #9

Updated by Michael Kay almost 3 years ago

  • Category set to DOM Interface
  • Status changed from New to Resolved
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Applies to branch 10, 11, trunk added
  • Fix Committed on Branch 10, trunk added
Actions #10

Updated by Michael Kay almost 3 years ago

The patch causes a failure in unit test RennauBugs.writeToResult1, in which the node supplied in a DOMResult is not (yet) attached to any document or document fragment. We need to test for null as we move up the parent axis in DOMWriter.getAllNamespaces()

Actions #11

Updated by O'Neil Delpratt almost 3 years ago

  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 11.1 added
  • Platforms .NET, Java added

Bug fix applied in the Saxon 11.1 release.

Actions #12

Updated by O'Neil Delpratt almost 3 years ago

Leaving bug as resolved until fix applied to the Saxon 10 maintenance release.

Actions #13

Updated by Debbie Lockett almost 3 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 10.7 added
  • Fixed in Maintenance Release deleted (11.1)

Bug fix applied in the Saxon 10.7 maintenance release.

Actions #14

Updated by Debbie Lockett almost 3 years ago

  • Fixed in Maintenance Release 11.1 added

Please register to edit this issue

Also available in: Atom PDF