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 消息或 将架构合并到一个文件中。