JAXB对根元素感到困惑?

时间:2011-12-15 21:00:27

标签: java jaxb visio

我正在尝试使用Visio XML Schema编组文件,该文件由3个模式文件组成,并在使用XJC生成java源时生成三个包:

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

根元素是VisioDocument,我正在使用的所有类都在2003包中。

以下是我编组XML文件的方法:

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

执行时,我收到此错误:

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]

我正在使用PagePropsType,但它不是根元素。为什么JAXB认为它是?

2 个答案:

答案 0 :(得分:2)

问题在于代码的... manipulated here ...部分。

基于您执行以下操作(或类似内容)的假设。

// you create a page prop
PagePropsType pageProps = ...

// then you feed it to a shape sheet
ShapeSheetType shapeSheet = ...
shapeSheet.getTextOrXFormOrLine().add(pageProps);

ShapeSheetTypeStyleSheetType的超类,等等。)

如果是这种情况,那么问题在于直接将pageProps添加到列表中。

如果您查看getTextOrXFormOrLine()方法的文档,它会列出列表可以容纳的类型。每个类型都包含在JAXBElement<...>中,因此您必须先将pageProps换行,然后再将其添加到列表中。

你应该这样做:

ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<PagePropsType> pagePropsElement = objectFactory.createShapeSheetTypePageProps(pageProps);

(注意我已经使用XJC 2.2.4编译模式;对我来说,每个类的名称后缀为Type。也许这就是为什么我最终得到了VisioDocumentType而不是像你这样的VisioDocument,但这无关紧要。)

答案 1 :(得分:1)

如果您检查生成的代码,则会在其中找到ObjectFactory课程。这个类应该有一个返回VisioDocument包裹在JAXBElement中的方法,并且它是你想要传递给编组器的对象。

同样适用于您在VisioDocument中设置的所有对象 - 请勿使用“new”创建它们,而是使用ObjectFactory