我们遇到了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严格。
所以问题是:
答案 0 :(得分:2)
不,正如您所述,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属性即可。它没有在这里做任何有用的事情,因为元素名称足以识别所需的类型。