I'm trying to marshal a file using the Visio XML Schema, which consists of 3 schema files and produces three packages when java source is generated with XJC:
The root element is VisioDocument
, and all of the classes I'm using are in the 2003
package.
Here is my approach to marshalling my XML file:
VisioDocumentType visioDoc = new VisioDocumentType();
... manipulated here ...
JAXBContext jc = JAXBContext.newInstance("com.microsoft.schemas.visio._2003.core");
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(new JAXBElement<VisioDocumentType>(new QName("uri","local"), VisioDocumentType.class, visioDoc), bw);
When executed, I receive this error:
javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "com.microsoft.schemas.visio._2003.core.PagePropsType" as an element because it is missing an @XmlRootElement annotation]
I am using PagePropsType
, but it is not a root element. Why does JAXB think it is?
The problem resides in the ... manipulated here ...
part of your code.
Based on the assumption that you do the following (or something similar).
// you create a page prop
PagePropsType pageProps = ...
// then you feed it to a shape sheet
ShapeSheetType shapeSheet = ...
shapeSheet.getTextOrXFormOrLine().add(pageProps);
(ShapeSheetType
is a superclass for StyleSheetType
, et cetera.)
If this's the case, then your problem lies in adding the pageProps
to the list directly.
If you take a look at the getTextOrXFormOrLine()
method's documentation it lists what kind of types the list can hold. Every type is wrapped in a JAXBElement<...>
so you have to wrap pageProps
before adding it to the list.
You should do it like this:
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<PagePropsType> pagePropsElement = objectFactory.createShapeSheetTypePageProps(pageProps);
(Note that I've used XJC 2.2.4 to compile the schemas; for me every class' name is suffixed with Type
. Maybe this is why I ended up with VisioDocumentType
instead of VisioDocument
like you, but it shouldn't matter.)
If you check your generated code, you will find a ObjectFactory
class in there. This class should have a method that returns a VisioDocument
wrapped in a JAXBElement
, and that it the object that you want to pass to the marshaller.
Same applicable to all objects you set inside VisioDocument
- don't create them with 'new
' but use ObjectFactory
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With