JAXB minOccurs和UnmarshalException

时间:2011-02-23 21:00:54

标签: xml xsd jaxb

我使用xjc生成了类,我正在尝试处理以下XML文档。 我收到了错误:

javax.xml.bind.UnmarshalException: Unexpected end of element {http://schemas.xmlsoap.org/soap/envelope/}:Body

我认为这是因为XML不包含Fault元素(当我添加一个fault元素时,它确实处理没有错误。 响应将包含RETRIEVAL_ID或Fault,但不包含两者。我认为在模式中使用minOccurs = 0会解决这个问题,但是没有去(至少我是怎么做的)。 是否可以在这种情况下使用JAXB,也就是说,当这些元素中的任何一个存在时,但不能同时存在这两个元素?

有问题的XML响应:

<?xml version = '1.0' encoding = 'UTF-8'?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<env:Header>
  <bmw:rule xmlns:bmw="http://adr.com/bmw">
     <bmw:customer>44</bmw:customer>
     <bmw:schemaName>ABC</bmw:schemaName>
     <bmw:schemaVersion>1.0</bmw:schemaVersion>
  </bmw:rule>
</env:Header>
<env:Body>
  <bmw:RETRIEVAL_ID xmlns:bmw="http://adr.com/bbs">15086</bmw:RETRIEVAL_ID>
</env:Body>
</env:Envelope>

架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bmw="http://adr.com/bmw">
<xs:import namespace="http://adr.com/bmw" schemaLocation="bmw.xsd"/>
<xs:element name="Envelope">
<xs:complexType>
  <xs:sequence>
    <xs:element ref="env:Header"/>
    <xs:element ref="env:Body"/>
  </xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Header">
<xs:complexType>
  <xs:sequence>
    <xs:element ref="bmw:rule"/>
  </xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Body">
<xs:complexType>
  <xs:sequence>
    <xs:element ref="bmw:RETRIEVAL_ID" minOccurs="0"/>
    <xs:element ref="env:Fault" minOccurs="0"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
<xs:element name="Fault">
<xs:complexType>
  <xs:sequence>
    <xs:element ref="bmw:fault"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
</xs:schema>

1 个答案:

答案 0 :(得分:0)

现在你的complexType包含:

<xs:complexType>
  <xs:sequence>
    <xs:element ref="bmw:RETRIEVAL_ID" minOccurs="0"/>
    <xs:element ref="env:Fault" minOccurs="0"/>
  </xs:sequence>
 </xs:complexType>

如果在指定时间只显示一个,则需要xs:choice而不是xs:sequence。有关详情,请参阅this

<xs:complexType>
  <xs:choice>
    <xs:element ref="bmw:RETRIEVAL_ID" minOccurs="0"/>
    <xs:element ref="env:Fault" minOccurs="0"/>
  </xs:choice>
 </xs:complexType>

您需要在更改架构后使用xjc重新生成类文件,以便在Java中反映更改。

This article from Oracle有一小部分介绍JAXB如何处理choiceThis blog post有一个相当全面的choice和JAXB示例。重要的是要注意:

@XmlElements(value = {
            @XmlElement(name="RETRIEVAL_ID",
                        type=RetrievalID.class),
            @XmlElement(name="FAULT",
                        type=Fault.class)
    })
Object possibleValue;

在Java中。