【问题标题】:JAXB is confused about root elements?JAXB 对根元素感到困惑?
【发布时间】:2011-12-15 21:00:26
【问题描述】:

我正在尝试使用 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 会这么认为?

【问题讨论】:

  • 你在注释上设置com.microsoft.schemas.visio._2003.core.PagePropsType实例的属性如何?
  • @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "PageProps_Type", propOrder = { "pageWidthOrPageHeightOrShdwOffsetX" }) 这就是你要找的吗?
  • 我的意思是您将实例设置到的属性,而不是 PagePropsType 本身。
  • 这是我要添加到的对象:snipt.org/qKT3

标签: java jaxb visio


【解决方案1】:

问题在于代码的... 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&lt;...&gt; 中,因此您必须先包裹 pageProps,然后才能将其添加到列表中。

你应该这样做:

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

(请注意,我使用 XJC 2.2.4 来编译模式;对我来说,每个类的名称都以 Type 为后缀。也许这就是我最终使用 VisioDocumentType 而不是 @987654332 的原因@喜欢你,但没关系。)

【讨论】:

  • 这似乎是我所缺少的,谢谢。 (缺少Type 是一个错字)
【解决方案2】:

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

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

【讨论】:

  • 我这样做了,但问题仍然存在。
  • 同样适用于您在 VisioDocument 中设置的所有对象 - 不要使用“新”创建它们,而是使用 ObjectFactory。 我认为应该并且必须使用 ObjectFactory 如果必须创建一个包含在JAXBElement&lt;...&gt; 中的类型,否则只会污染代码。无论如何,ObjectFactory 中的 createXxxType 之类的方法只调用 new XxxType()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 2012-07-22
  • 2013-05-13
  • 2020-04-16
  • 2023-03-08
  • 2019-08-04
  • 2019-12-30
相关资源
最近更新 更多