Bug #5196
closedMissing default namespace attribute on transform to DOM
100%
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
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.
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.
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.
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.
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], ""));
}
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.
Updated by Michael Kay almost 3 years ago
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).
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
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()
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.
Updated by O'Neil Delpratt almost 3 years ago
Leaving bug as resolved until fix applied to the Saxon 10 maintenance release.
Updated by Debbie Lockett over 2 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.
Updated by Debbie Lockett over 2 years ago
- Fixed in Maintenance Release 11.1 added
Please register to edit this issue