5

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:

  • com.microsoft.schemas.visio._2003.core
  • com.microsoft.schemas.visio._2006.extension
  • com.microsoft.schemas.office.visio._2010.extension

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?

Chris
  • 3,400
  • 1
  • 27
  • 41
  • How is the property you are setting the instance of `com.microsoft.schemas.visio._2003.core.PagePropsType` on annotated? – bdoughan Dec 15 '11 at 21:12
  • `@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "PageProps_Type", propOrder = { "pageWidthOrPageHeightOrShdwOffsetX" })` Is that what you're looking for? – Chris Dec 15 '11 at 21:19
  • I meant the property you are setting the instance onto and not the `PagePropsType` itself. – bdoughan Dec 15 '11 at 21:20
  • Here is the object I'm adding it to: http://snipt.org/qKT3 – Chris Dec 15 '11 at 21:38

2 Answers2

2

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.)

Kohányi Róbert
  • 9,791
  • 4
  • 52
  • 81
1

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.

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
maximdim
  • 8,041
  • 3
  • 33
  • 48
  • I did this but the problems remains. – Chris Dec 15 '11 at 21:35
  • _Same applicable to all objects you set inside VisioDocument - don't create them with 'new' but use ObjectFactory._ In my opinion `ObjectFactory` should and have to be used _only_ if one have to create a type wrapped in `JAXBElement<...>`, otherwise it just pollutes the code. Methods like `createXxxType` in `ObjectFactory` only calls `new XxxType()` anyway. – Kohányi Róbert Dec 16 '11 at 11:38