Discrepancy in marshal behaviour

2019-08-09 14:45发布

问题:

I am testing MOXy 2.5.0 RC1.

I marshalled the following to a string:

  <c r="C3"  xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
    <v>20</v>
  </c>

It is represented by https://github.com/plutext/docx4j/blob/master/src/xlsx4j/java/org/xlsx4j/sml/Cell.java

Notice the absence of any @XmlRootElement annotation

With the reference implementation, the result, as expected, is:

javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "org.xlsx4j.sml.Cell" as an element because it is missing an @XmlRootElement annotation]
        at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:317)
        at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:243)
        at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96)
        at org.docx4j.XmlUtils.marshaltoString(XmlUtils.java:507)

With MOXy, the result is:

 <v>20</v>

Is this a known issue? I haven't tried 2.4.2 RC1.

thanks..

回答1:

That is a known difference between EclipseLink MOXy and the RI. We have left this door open in MOXy for the use case where you are marshalling into an OutputStream or Writer where the root element has already been written.

Are you counting on an exception being thrown. When there is no root element you can wrap the object in an instance of JAXBElement.

Workaround

You can use a JAXBIntrospector to determine if an object has a root element.

JAXBIntrospector introspector = jaxbContext.createJAXBIntrospector();
QName rootElement = introspector.getElementName(aPOJO);
if(null == rootElement) {
    // ...
} else {
    // ...
}