Skip to content

Missing namespace when marshalling org.w3c.dom.Element with namespaced attribute #2390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
blutorange opened this issue Mar 30, 2025 · 0 comments

Comments

@blutorange
Copy link

blutorange commented Mar 30, 2025

Describe the bug

When MOXY marshals an org.w3c.dom.Element, it correctly includes the namespace of the element. However, any namespaces for attributes are ignored and never make it into the marshalled XML, leading to invalid XML files.

For example, let's say you have the following annotated class:

@XmlRootElement(name = "bugdemo.MyXmlAnyElementType")
public class MyXmlAnyElementType {
	@XmlAnyElement(lax = false)
	public Element someXmlBlock;
}

And you create an instance with some DOM element with a namespace attribute:

MyXmlAnyElementType el = new MyXmlAnyElementType();

Document doc = newDocument();
Element x = doc.createElementNS("http://example.com/element", "x");
x.setAttributeNS("http://example.com/attribute", "attr", "value");
Element y = doc.createElementNS("http://example.com/element2", "y");
x.appendChild(y);

el.someXmlBlock = x;

Then moxy creates the following XML

<?xml version="1.0" encoding="UTF-8"?>
<bugdemo.MyXmlAnyElementType xmlns="urn:testcase">
   <x attr="value" xmlns="http://example.com/element">
      <y xmlns="http://example.com/element2"/>
   </x>
</bugdemo.MyXmlAnyElementType>

The default glassfish JAXB implementation produces correct XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bugdemo.MyXmlAnyElementType xmlns="urn:testcase">
    <x ns0:attr="value" xmlns="http://example.com/element" xmlns:ns0="http://example.com/attribute">
        <y xmlns="http://example.com/element2"/>
    </x>
</bugdemo.MyXmlAnyElementType>

Context: I first encountered it with generated Java files for the BPMN2 XSD schema files (which allows custom extension elements).

To Reproduce

Reproducer: https://github.com/blutorange/moxybug/tree/demo-bug-attr-ns

Simply run mvn test. Seems to happen with any namespaced attribute.

https://github.com/blutorange/moxybug/blob/4fcfc78178f15d22d88177d008a1660ada70ea1a/src/test/java/bugdemo/Testcase.java#L26-L43

  • EclipseLink version: 4.0.5
  • Java/JDK version: 17

Expected behavior

Moxy should output XML where the namespace of the attribute matches the namespace as defined programmatically in the org.w3c.dom.Element.

Note

Manually setting a prefix on the org.w3c.dom.Attr results in moxy outputting the prefix, but it's still missing the namespace.

From a little big of debugging, I found XMLFragmentReader#handlePrefixedAttribute, and while that method inspects an element's attributes, it only seems to check for xmlns and ignores everything else. That method seems to be responsible for why it works for org.w3c.dom.Element

if(attributes != null) {
for(int x=0; x < attributes.getLength(); x++) {
Node attribute = attributes.item(x);
if(XMLConstants.XMLNS_ATTRIBUTE.equals(attribute.getPrefix())) {
NamespaceResolver tmpresolver = getTempResolver(elem);
tmpresolver.put(attribute.getLocalName(), attribute.getNodeValue());
if (!nsresolverList.contains(tmpresolver)) {
nsresolverList.add(tmpresolver);
}
} else if(XMLConstants.XMLNS_ATTRIBUTE.equals(attribute.getNodeName())) {
NamespaceResolver tmpresolver = getTempResolver(elem);
String namespace = attribute.getNodeValue();
if(null == namespace) {
namespace = Constants.EMPTY_STRING;
}
tmpresolver.put(Constants.EMPTY_STRING, namespace);
if (!nsresolverList.contains(tmpresolver)) {
nsresolverList.add(tmpresolver);
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant