Jaxb2Marshaller cvc-elt.1:即使 class 元素已知,也找不到元素声明
Jaxb2Marshaller cvc-elt.1: Cannot find the declaration of element even though the class element is known
我写了两个 XSD 来生成模型并在调用 Web 服务时验证主体。
我用来生成模型的 Maven 插件是:org.codehaus.mojo:jaxb2-maven-plugin:2.3
它从以下 XSDs 成功生成了正确的模型:
requests.xsd:
<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SLIR" type="SLIRType"/>
<!-- region ENUMS -->
<xs:simpleType name="PriorityTypeType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="NORMAL"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LocationTypeType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="LAST"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="WGSType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="WGS-84"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CoordSystemType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="LL"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MSIDEncType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="ASC"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MSIDTypeType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="MSISDN"/>
</xs:restriction>
</xs:simpleType>
<!-- endregion -->
<xs:complexType name="SLIRType">
<xs:all>
<xs:element type="ClientType" name="CLIENT"/>
<xs:element type="MSIDListType" name="MSIDS"/>
<xs:element type="GeoInfoType" name="GEO_INFO"/>
<xs:element type="LocationType" name="LOC_TYPE"/>
<xs:element type="PriorityType" name="PRIO"/>
<xs:element type="EQoPType" name="EQoP" minOccurs="0"/>
</xs:all>
<xs:attribute type="xs:string" name="ver" default="1.0"/>
</xs:complexType>
<xs:complexType name="ClientType">
<xs:sequence>
<xs:element type="xs:string" name="ID"/>
<xs:element type="xs:string" name="PWD"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSIDType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="MSIDEncType" name="msid_enc" use="required"/>
<xs:attribute type="MSIDTypeType" name="msid_type" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="MSIDListType">
<xs:sequence>
<xs:element type="MSIDType" name="MSID" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="GeoInfoType">
<xs:attribute type="WGSType" name="datum" use="required"/>
<xs:attribute type="CoordSystemType" name="coord_sys" use="required"/>
</xs:complexType>
<xs:complexType name="LocationType">
<xs:attribute type="LocationTypeType" name="loc_type_type" use="required"/>
</xs:complexType>
<xs:complexType name="PriorityType">
<xs:attribute type="PriorityTypeType" name="prio_type" use="required"/>
</xs:complexType>
<xs:complexType name="EQoPType">
<!-- unknown -->
</xs:complexType>
</xs:schema>
responses.xsd:
<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SLIA" type="SLIAType"/>
<xs:complexType name="LL_POINTType">
<xs:sequence>
<xs:element type="xs:double" name="LAT"/>
<xs:element type="xs:double" name="LONG"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="POINTType">
<xs:sequence>
<xs:element type="LL_POINTType" name="LL_POINT"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CIRCLEType">
<xs:sequence>
<xs:element type="POINTType" name="POINT"/>
<xs:element type="xs:integer" name="RAD"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SHAPEType">
<xs:sequence>
<xs:element type="CIRCLEType" name="CIRCLE"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PDType">
<xs:sequence>
<xs:element type="xs:integer" name="TIME"/>
<xs:element type="SHAPEType" name="SHAPE"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="POSERRResultType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="resid"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="POSERRType">
<xs:sequence>
<xs:element type="POSERRResultType" name="RESULT" />
<xs:element type="xs:string" name="TIME" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="POSType">
<xs:sequence>
<xs:element type="xs:string" name="MSID"/>
<xs:choice minOccurs="0">
<xs:element type="PDType" name="PD"/>
<xs:element type="POSERRType" name="POSERR"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RESULTType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="resid"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="SLIAType">
<xs:sequence>
<xs:element type="POSType" name="POS" minOccurs="0"/>
<xs:element type="xs:string" name="GMT_OFF"/>
<xs:element type="RESULTType" name="RESULT"/>
<xs:element type="xs:string" name="ADD_INFO" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="ver"/>
</xs:complexType>
</xs:schema>
现在,编组使用生成的 ObjectFactory 创建的对象工作正常,但解组我从 Web 服务收到的主体,例如:
<SLIA ver="1.0">
<POS>
<MSID>ah827cgs</MSID>
<PD>
<TIME>20191025112228</TIME>
<SHAPE>
<CIRCLE>
<POINT>
<LL_POINT>
<LAT></LAT>
<LONG></LONG>
</LL_POINT>
</POINT>
<RAD>500</RAD>
</CIRCLE>
</SHAPE>
</PD>
</POS>
<GMT_OFF>+0000</GMT_OFF>
<RESULT resid="0">OK</RESULT>
</SLIA>
报错org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 17; cvc-elt.1: Cannot find the declaration of element 'SLIA'.
。到目前为止,我得出的结论是,这是因为没有定义的命名空间,但我无法控制它,我也不想控制它,而且在这样一个受限的上下文中解组时肯定没有关系(有限已知元素和预定义元素的数量 XML).
我正在这样配置 Jaxb2Marshaller:
@Bean
public Jaxb2Marshaller marshaller(
@Value("classpath:/schemas/gmlc-requests.xsd") Resource reqSchema,
@Value("classpath:/schemas/gmlc-responses-new.xsd") Resource resSchema
) {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("xml.gmlc.v1.request.**", "xml.gmlc.v1.response.**");
marshaller.setSchemas(reqSchema, resSchema);
return marshaller;
}
并像这样使用它:
Object sliaElement = marshaller.unmarshal(new StringSource(xmlResponse));
有没有办法让 Jaxb2Marshaller
解组此响应消息,同时还使用响应 XSD 对其进行验证?它应该保留在默认命名空间中。
使用外部验证器网站为其提供响应 XSD 和上面提到的正文,结果有效,所以我认为 XSD 没有错,并查看源代码Jaxb2Marshaller 的代码,这个错误来自模式验证,所以那里发生了一些奇怪的事情。
为什么元素会拆分成 2 个 XSD?我相信问题出在 setSchemas 方法中。 Jaxb 将尝试根据第一个匹配的模式(基于名称空间)进行验证;这将是 requestSchema。
尝试仅提供单一模式并解组相应的 xml 消息或
将架构合并到一个文件中。
我写了两个 XSD 来生成模型并在调用 Web 服务时验证主体。
我用来生成模型的 Maven 插件是:org.codehaus.mojo:jaxb2-maven-plugin:2.3
它从以下 XSDs 成功生成了正确的模型:
requests.xsd:
<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SLIR" type="SLIRType"/>
<!-- region ENUMS -->
<xs:simpleType name="PriorityTypeType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="NORMAL"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="LocationTypeType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="LAST"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="WGSType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="WGS-84"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="CoordSystemType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="LL"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MSIDEncType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="ASC"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MSIDTypeType" final="restriction">
<xs:restriction base="xs:token">
<xs:enumeration value="MSISDN"/>
</xs:restriction>
</xs:simpleType>
<!-- endregion -->
<xs:complexType name="SLIRType">
<xs:all>
<xs:element type="ClientType" name="CLIENT"/>
<xs:element type="MSIDListType" name="MSIDS"/>
<xs:element type="GeoInfoType" name="GEO_INFO"/>
<xs:element type="LocationType" name="LOC_TYPE"/>
<xs:element type="PriorityType" name="PRIO"/>
<xs:element type="EQoPType" name="EQoP" minOccurs="0"/>
</xs:all>
<xs:attribute type="xs:string" name="ver" default="1.0"/>
</xs:complexType>
<xs:complexType name="ClientType">
<xs:sequence>
<xs:element type="xs:string" name="ID"/>
<xs:element type="xs:string" name="PWD"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MSIDType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="MSIDEncType" name="msid_enc" use="required"/>
<xs:attribute type="MSIDTypeType" name="msid_type" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="MSIDListType">
<xs:sequence>
<xs:element type="MSIDType" name="MSID" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="GeoInfoType">
<xs:attribute type="WGSType" name="datum" use="required"/>
<xs:attribute type="CoordSystemType" name="coord_sys" use="required"/>
</xs:complexType>
<xs:complexType name="LocationType">
<xs:attribute type="LocationTypeType" name="loc_type_type" use="required"/>
</xs:complexType>
<xs:complexType name="PriorityType">
<xs:attribute type="PriorityTypeType" name="prio_type" use="required"/>
</xs:complexType>
<xs:complexType name="EQoPType">
<!-- unknown -->
</xs:complexType>
</xs:schema>
responses.xsd:
<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SLIA" type="SLIAType"/>
<xs:complexType name="LL_POINTType">
<xs:sequence>
<xs:element type="xs:double" name="LAT"/>
<xs:element type="xs:double" name="LONG"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="POINTType">
<xs:sequence>
<xs:element type="LL_POINTType" name="LL_POINT"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CIRCLEType">
<xs:sequence>
<xs:element type="POINTType" name="POINT"/>
<xs:element type="xs:integer" name="RAD"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SHAPEType">
<xs:sequence>
<xs:element type="CIRCLEType" name="CIRCLE"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PDType">
<xs:sequence>
<xs:element type="xs:integer" name="TIME"/>
<xs:element type="SHAPEType" name="SHAPE"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="POSERRResultType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="resid"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="POSERRType">
<xs:sequence>
<xs:element type="POSERRResultType" name="RESULT" />
<xs:element type="xs:string" name="TIME" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="POSType">
<xs:sequence>
<xs:element type="xs:string" name="MSID"/>
<xs:choice minOccurs="0">
<xs:element type="PDType" name="PD"/>
<xs:element type="POSERRType" name="POSERR"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RESULTType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="resid"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="SLIAType">
<xs:sequence>
<xs:element type="POSType" name="POS" minOccurs="0"/>
<xs:element type="xs:string" name="GMT_OFF"/>
<xs:element type="RESULTType" name="RESULT"/>
<xs:element type="xs:string" name="ADD_INFO" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="ver"/>
</xs:complexType>
</xs:schema>
现在,编组使用生成的 ObjectFactory 创建的对象工作正常,但解组我从 Web 服务收到的主体,例如:
<SLIA ver="1.0">
<POS>
<MSID>ah827cgs</MSID>
<PD>
<TIME>20191025112228</TIME>
<SHAPE>
<CIRCLE>
<POINT>
<LL_POINT>
<LAT></LAT>
<LONG></LONG>
</LL_POINT>
</POINT>
<RAD>500</RAD>
</CIRCLE>
</SHAPE>
</PD>
</POS>
<GMT_OFF>+0000</GMT_OFF>
<RESULT resid="0">OK</RESULT>
</SLIA>
报错org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 17; cvc-elt.1: Cannot find the declaration of element 'SLIA'.
。到目前为止,我得出的结论是,这是因为没有定义的命名空间,但我无法控制它,我也不想控制它,而且在这样一个受限的上下文中解组时肯定没有关系(有限已知元素和预定义元素的数量 XML).
我正在这样配置 Jaxb2Marshaller:
@Bean
public Jaxb2Marshaller marshaller(
@Value("classpath:/schemas/gmlc-requests.xsd") Resource reqSchema,
@Value("classpath:/schemas/gmlc-responses-new.xsd") Resource resSchema
) {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("xml.gmlc.v1.request.**", "xml.gmlc.v1.response.**");
marshaller.setSchemas(reqSchema, resSchema);
return marshaller;
}
并像这样使用它:
Object sliaElement = marshaller.unmarshal(new StringSource(xmlResponse));
有没有办法让 Jaxb2Marshaller
解组此响应消息,同时还使用响应 XSD 对其进行验证?它应该保留在默认命名空间中。
使用外部验证器网站为其提供响应 XSD 和上面提到的正文,结果有效,所以我认为 XSD 没有错,并查看源代码Jaxb2Marshaller 的代码,这个错误来自模式验证,所以那里发生了一些奇怪的事情。
为什么元素会拆分成 2 个 XSD?我相信问题出在 setSchemas 方法中。 Jaxb 将尝试根据第一个匹配的模式(基于名称空间)进行验证;这将是 requestSchema。
尝试仅提供单一模式并解组相应的 xml 消息或 将架构合并到一个文件中。