开发者

JAXB minOccurs and UnmarshalException

I generated classes using xjc, and I am trying to process the following XML doc. I am getting the error:

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

I believe it is because the XML does NOT contain the Fault element (when I add in a fault element, it does process without errors. The response will either contain the RETRIEVAL_ID or the Fault, but never both. I thought having the minOccurs=0 in the schema would fix this, but no go (at least how I did it). Is it possible to use JAXB for this situation, that is, when either of these elements may exist, but never both at the same time?

XML Response in question:

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

Schema:

<?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:complexTyp开发者_开发问答e>
  <xs:sequence>
    <xs:element ref="bmw:fault"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
</xs:schema>


Right now your complexType contains:

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

If only one appears at a given time, you want xs:choice instead of xs:sequence. See this for more.

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

You will need to regenerate your class files using xjc after changing your schema for the change to be reflected in the Java.

This article from Oracle has a small section on how JAXB handles choice. This blog post has a fairly comprehensive example of choice and JAXB. The important thing to note is that you will have:

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

in your Java.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜