xml - Jaxb2Marshaller cvc-elt.1:即使类元素已知,也找不到元素的声明
问题描述
我编写了两个 XSD 来生成模型并在调用 Web 服务时验证主体。
我用来生成模型的 Maven 插件是:org.codehaus.mojo:jaxb2-maven-plugin:2.3
它成功地从以下 XSD 生成了正确的模型:
请求.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>
响应.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 消息或将模式组合到一个文件中。
推荐阅读
- python - numpy.float32 到浮点转换不起作用
- javascript - 获取元素的css定义
- entity-framework - 使用带有复合主键的 .Find 使用 MOQ 和 EFCore 进行单元测试
- kubernetes - 移动或更改卷命名空间
- javascript - NodeJS 和 Express - 子字符串搜索
- c# - 从 SQL Server 检索新插入的 ID 列并使用 c# 在文本框字段中显示
- javascript - 设置时表没有最小高度
- typescript - 与“keyof interface”相比,“keyof typeof value”产生不同的类型结果
- javascript - 箭头函数在 Javascript 对象中的行为如何?
- r - ggplot2中离散变量的累积计数