JAXB 无法解组某些替换组

发布于 2024-11-15 15:49:53 字数 1672 浏览 0 评论 0原文

我在解组已根据架构验证的 XML 时遇到问题。

我提供了一个已扩展的大型架构。以下是所提供内容的片段:(

命名空间“original”)

<xs:element name="Platform" type="PlatformType" abstract="true" />

<xs:complexType name="PlatformType" abstract="true">
   ...
</xs:complexType>

<xs:element name="SpringPlatform" type="SpringPlatformType" substitutionGroup="Platform" />

<xs:complexType name="SpringPlatformType">
    <xs:complexContent>
        <xs:extension base="PlatformType">
            ...
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

现在我已经使用一些附加功能扩展了 SpringPlatformType:

<xsd:element name="MySpringPlatform" type="MySpringPlatformType"
        substitutionGroup="original:SpringPlatform" />

<xsd:complexType name="MySpringPlatformType">
    <xsd:complexContent>
        <xsd:extension base="original:SpringPlatformType">
            <xsd:sequence>
                ...
            </xsd:sequence>
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

我收到了一个平台列表,如下所示:

<xs:element name="PlatformList" type="PlatformListType" />

<xs:complexType name="PlatformListType">
    <xs:sequence>
        <xs:element ref="Platform" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

我可以正确地解组使用原始版本的传入消息:SpringPlatform元素,但是当我尝试解组我的派生/扩展类型 (MySpringPlatform) 时,我得到 null。 但是,XML 使用 XMLSpy 根据我的架构进行验证2011年还好。

有什么建议吗?我在 Java 6u24、Windows XP SP3 上使用 JAXB (Metro) 2.2.4。

谢谢,

布莱恩

I'm having issues unmarshalling XML that has been validated against a schema.

I have a large schema provided to me that I have extended. Here's a snippet of what's provided:

(Namespace "original")

<xs:element name="Platform" type="PlatformType" abstract="true" />

<xs:complexType name="PlatformType" abstract="true">
   ...
</xs:complexType>

<xs:element name="SpringPlatform" type="SpringPlatformType" substitutionGroup="Platform" />

<xs:complexType name="SpringPlatformType">
    <xs:complexContent>
        <xs:extension base="PlatformType">
            ...
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

Now I've extended SpringPlatformType with some additional functionality:

<xsd:element name="MySpringPlatform" type="MySpringPlatformType"
        substitutionGroup="original:SpringPlatform" />

<xsd:complexType name="MySpringPlatformType">
    <xsd:complexContent>
        <xsd:extension base="original:SpringPlatformType">
            <xsd:sequence>
                ...
            </xsd:sequence>
        </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

I am receiving a list of Platforms, like this:

<xs:element name="PlatformList" type="PlatformListType" />

<xs:complexType name="PlatformListType">
    <xs:sequence>
        <xs:element ref="Platform" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

I can correctly unmarshall incoming messages that use the original:SpringPlatform elements, but when I try to unmarshall my derived/extended types (MySpringPlatform), I get null. However, the XML validates against my schemas using XMLSpy 2011 just fine.

Any suggestions? I am using JAXB (Metro) 2.2.4 on Java 6u24, Windows XP SP3.

Thanks,

Brian

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

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

发布评论

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

评论(1

我爱人 2024-11-22 15:49:53

当您创建 JAXB 解组器时,您需要向其传递上下文;也就是说,您正在解组的结构的包。我们使用了一个实用程序类,它使我们可以轻松地执行此操作:将 XML 字符串和包名称传递给它,然后您将返回一个对象。

但是,当解组跨多个命名空间和包的结构时,您需要为引用的每个包提供包名称,否则解组器没有正确的上下文。我从来不知道您可以将多个包名称传递到 JAXB 上下文。

错误:

// Pass package name for the message only.
JAXBContext jc = JAXBContext.newInstance("com.mycompany.my.messages");
Unmarshaller u = jc.createUnmarshaller();

正确:

// Pass package names for all XML structures present in the message.
JAXBContext jc = JAXBContext.newInstance("com.mycompany.my.types:com.mycompany.my.messages:com.othercompany.their.types");
Unmarshaller u = jc.createUnmarshaller();

也许这是一个愚蠢的错误,但我想我应该分享以防万一。阅读一点 site 给了我这个想法。上面的 lexcore 也提到了这一点,但我认为他在谈论类路径问题;所有生成的类始终可供上下文使用,但是上下文并没有被告知要查找它们。

When you create a JAXB unmarshaller, you need to pass it the context; that is, the package of the structure you're unmarshalling. We were using a utility class that made it easy for us to do this: pass it the XML string and a package name, and you get back an Object.

However, when unmarshalling structures that span across multiple namespaces and packages, you need to provide the package name for every package referenced, otherwise the unmarshaller doesn't have the right context. I never knew you could pass multiple package names to the JAXB context.

WRONG:

// Pass package name for the message only.
JAXBContext jc = JAXBContext.newInstance("com.mycompany.my.messages");
Unmarshaller u = jc.createUnmarshaller();

RIGHT:

// Pass package names for all XML structures present in the message.
JAXBContext jc = JAXBContext.newInstance("com.mycompany.my.types:com.mycompany.my.messages:com.othercompany.their.types");
Unmarshaller u = jc.createUnmarshaller();

Maybe this was a stupid mistake, but I figured I would share just in case. Reading a bit on this site provided me with the idea. lexicore above also alluded to this, but I thought he was talking about classpath issues; all of the generated classes were always available to the context, however the context wasn't being told to look for them.

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