为本地complexType指定xsi:type是否有效?

时间:2014-03-19 05:34:56

标签: xml xml-parsing jaxb xsd jaxb2

我们遇到了xsi:type的问题,因为我们的服务器升级到jaxb 2.当服务器运行jaxb 1时,有问题的xml客户端请求被解析了,但是由于升级到jaxb 2,我们看到了一个错误。以下几行:

Error::cvc-elt.4.2: Cannot resolve 'er-request' to a type definition for element 'er-request'

客户端指定xsi:type作为xml标记中的属性,但我认为它不合适,因为有问题的复杂类型没有这样的名称。

<?xml version="1.0" encoding="UTF-8"?>
<er-request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="100007" xsi:type="er-request">
    <payload>
     <!--some content-->
    </payload>
</er-request>

这是xsd:

<xs:element name="er-request">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="payload" type="payloadType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="id" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:int"/>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
</xs:element>

<xs:complexType name="payloadType">
    <xs:sequence>
        <xs:any processContents="skip" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>

因此,您可以看到complexType中没有name属性。我们可以通过添加它来解决错误,但之后我们看到验证错误,因为显然是本地complexType上的name属性:

Attribute 'name' cannot appear in element 'complexType'

我认为这在jaxb1中起作用的原因是它不如jaxb 2严格。

所以问题是:

  1. 是客户端xml有效吗?
  2. 我们可以尝试让jaxb2更宽松吗?

2 个答案:

答案 0 :(得分:2)

您的XML文档是否有效?

不,正如您所述,xsi:type属性的值与XML架构中的命名复杂类型不对应。

那应该重要吗?

JAXB实现旨在实现容错。在最新的JDK 1.7安装或EclipseLink JAXB(MOXy)中使用默认的JAXB impl,我无法让您的示例失败:

<强> ErRequest

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="er-request")
public class ErRequest {

}

<强>演示

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(ErRequest.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource xml = new StreamSource("src/forum22497112/input.xml");
        ErRequest erRequest = (ErRequest) unmarshaller.unmarshal(xml);

    }

}

来自

的错误在哪里

您获得的错误似乎是架构验证错误:

  

错误:: cvc-elt.4.2:无法解析“请求”&#39;到一个类型定义   对于元素&#39; er-request&#39;

您是否要求JAXB对输入执行架构验证?默认情况下,JAXB不会执行此操作。由于您的文档无效,您必须修复它或注册错误监听器才能忽略它。

答案 1 :(得分:1)

您需要将匿名复杂类型提升为全局(命名)类型:

<xs:element name="er-request" type="er-request"/>

<xs:complexType name="er-request">
        <xs:sequence>
            <xs:element name="payload" type="payloadType" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute name="id" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:int"/>
            </xs:simpleType>
        </xs:attribute>
</xs:complexType>

或者,只需删除xsi:type属性即可。它没有在这里做任何有用的事情,因为元素名称足以识别所需的类型。