JAXB 对根元素感到困惑?

发布于 2024-12-21 05:56:23 字数 1199 浏览 2 评论 0原文

我正在尝试使用 Visio XML 架构封送文件,由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 为什么这么认为?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦言归人 2024-12-28 05:56:23

问题出在代码的 ... 这里操作 ... 部分。

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

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

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

ShapeSheetTypeStyleSheetType 等的超类。)

如果是这种情况,那么您的问题在于添加 pageProps< /code> 直接添加到列表。

如果您查看 getTextOrXFormOrLine() 方法的文档,它会列出列表可以保存的类型。每种类型都包装在 JAXBElement<...> 中,因此您必须在将其添加到列表之前包装 pageProps

你应该这样做:

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

(请注意,我使用 XJC 2.2.4 来编译模式;对我来说,每个类的名称都以 Type 为后缀。也许这就是我结束的原因像您一样使用 VisioDocumentType 而不是 VisioDocument,但这应该不重要。)

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

北方的韩爷 2024-12-28 05:56:23

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文