【问题标题】:JAXB fails unmarshalling some substitutionGroupsJAXB 无法解组一些替代组
【发布时间】:2011-06-15 22:57:56
【问题描述】:

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

我有一个提供给我的大型架构,我已经对其进行了扩展。以下是所提供内容的 sn-p:

(命名空间“原始”)

<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。

谢谢,

布赖恩

【问题讨论】:

  • 如何创建 JAXBContext?
  • 我尝试了两种方法: 1) JAXBContext jc = JAXBContext.newInstance("package.name.here"); 2) JAXBContext jc = JAXBContext.newInstance(TypeName.class);
  • 确保 JAXBContext 可以使用原始命名空间和扩展命名空间的包。好像你只有原始包。
  • 我应该提一下,我在扩展命名空间中定义了其他对象(如 Header),这些对象(如 Header)解组就好了(即使在同一条消息中),所以我认为这不是可用包的问题.消息中的所有内容(还有很多其他内容)都将 except 解组为该替代组元素列表中的那些内容。

标签: xml xml-serialization xsd


【解决方案1】:

创建 JAXB 解组器时,需要将上下文传递给它;也就是说,您要解组的结构的包。我们使用了一个实用程序类,它使我们可以轻松地做到这一点:将 XML 字符串和包名传递给它,然后你会得到一个 Object。

但是,当解组跨越多个命名空间和包的结构时,您需要为引用的每个包提供包名称,否则解组器没有正确的上下文。我从不知道您可以将多个包名称传递给 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();

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    相关资源
    最近更新 更多