Bug #5196
closed
Missing default namespace attribute on transform to DOM
Applies to branch:
10, 11, trunk
Fix Committed on Branch:
10, trunk
Fixed in Maintenance Release:
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
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.
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.
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.
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.
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], ""));
}
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.
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.
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).
- 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
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()
- % 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.
Leaving bug as resolved until fix applied to the Saxon 10 maintenance release.
- 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.
- Fixed in Maintenance Release 11.1 added
Please register to edit this issue
Also available in: Atom
PDF