【问题标题】:JAXB minOccurs and UnmarshalExceptionJAXB minOccurs 和 UnmarshalException
【发布时间】:2011-07-03 02:16:03
【问题描述】:

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

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

我相信这是因为 XML 不包含错误元素(当我添加错误元素时,它确实处理没有错误。 响应将包含 RETRIEVAL_ID 或故障,但绝不会同时包含两者。我认为在架构中使用 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>

【问题讨论】:

    标签: xml xsd jaxb


    【解决方案1】:

    现在您的 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 中。

    【讨论】:

    • 我很好奇,我正在学习 xml、xsd、jaxb 等,你是怎么知道这个答案的,如果没有这个论坛,我怎么会知道这个答案?
    • @bmw0128 - 当我学习的时候,它是同事的组合,只是尝试一些东西,Oracle(然后是 Sun)文档,谷歌搜索教程,然后只是尝试直到他们工作。
    猜你喜欢
    • 2011-08-26
    • 2014-12-18
    • 1970-01-01
    • 2017-05-13
    • 2013-11-27
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多