Jaxb2Marshaller cvc-elt.1: не удается найти объявление элемента, даже если элемент класса известен - PullRequest
2 голосов
/ 30 октября 2019

Я написал два XSD для генерации модели и проверки тел при вызове веб-службы.

Плагин Maven, который я использовал для генерации модели: org.codehaus.mojo:jaxb2-maven-plugin:2.3, который успешно генерирует правильную модель из следующегоXSD:

reports.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>

response.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 работает нормально, но немаршаллизирующие тела, которые я получаю от веб-службы, такие как:

<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, эта ошибкапроисходит из проверки схемы, поэтому там происходит что-то странное.

1 Ответ

3 голосов
/ 30 октября 2019

Почему элементы разделены на 2 XSD? Я считаю, что проблема заключается в методе setSchemas. Jaxb попытается проверить первую подходящую схему (на основе пространства имен);которая будет являться запросом схемы.

Попробуйте предоставить только одну схему и разархивируйте соответствующее сообщение xml или объедините схему в один файл.

...