简体   繁体   中英

marshal/unmarshal 2 different classes that are based on 2 different schemas

Im trying to configure a jaxb2Marshaller in spring beans config file but Im pretty new to Spring and JAXB so i might be going about it the wrong way.

What i want to achieve is the same bean that will marshal/unmarshal 2 different classes that are based on 2 different schemas. Perhaps thats not possible because when i have both configured and run my tests they fail for the second class in the configuration (AccountResponse).

This is the XML configuration:

<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="marshallerProperties">
        <map>
            <entry key="com.sun.xml.bind.namespacePrefixMapper">
                <bean id="NamespacePrefixMapperImpl" class="org.lp.soa.controller.xml.LpsNamespacePrefixMapper" />
            </entry>
        </map>
    </property>
    <property name="classesToBeBound">
        <list>                              
            <value>org.lp.soa.controller.data.request.AccountRequest</value>
            <value>org.lp.soa.controller.data.response.AccountResponse</value>
        </list>
    </property>     
    <property name="schemas">
        <list>
        <value>classpath:schema/AccountRequest.xsd</value>
        <value>classpath:schema/AccountResponse.xsd</value>
        </list>
    </property>
</bean>

if i comment out the AccountRequest.xsd value from the config and then run my tests again the marshal/unmarshal for the second class (AccountResponse) they all pass, if I then uncomment it I get the error: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'accountResponse'.

Am i going about it the wrong way? Is it not supposed to be possible to handle two classes with two schemas?

Thanks, Yoav.

" if i comment out the AccountRequest.xsd value from the config and then run my tests again the marshal/unmarshal for the second class (AccountResponse) they all pass, if I then uncomment it I get the error: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'accountResponse'. "

Sounds like the Schema object being created by SchemaFactory.newSchema() is only processing the first xsd in the list.

If you have multiple schema files that are in the same namespace (targetNamespace?) then It could be this bug that is causing trouble:

https://issues.apache.org/jira/browse/XERCESJ-1130

What I did to work around this bug was creating a parent xsd file that included the other xsd files and then set the "schemaResourceResolver" property in the xml configuration with a LSResourceResolver implementation (See http://blog.frankel.ch/xml-validation-with-importedincluded-schemas for example)..

In your xml configuration add this:

parent.xsd file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://www.yourdomain.com/FIXED/EXAMPLE"
           targetNamespace="http://www.yourdomain.com/FIXED/EXAMPLE"
           elementFormDefault="qualified"
           version="1.000"
           id="some_id">
    <xs:include schemaLocation="AccountRequest.xsd"/>
    <xs:include schemaLocation="AccountResponse.xsd"/>
</xs:schema>

In your xml configuration change the schemas property to:

<property name="schemas">
        <list>
        <value>classpath:schema/parent.xsd</value>
        </list>
</property>

Try using MOXy . You could have a schema mapping defined by annotation, and the other mapping configured in a xml file.

As far as I know, XStream doesn't provide xml validations, so you could try to do a schema validation before unmarshal. Using JAXB you could validate required elements/attributes using @XmlElement/@XmlAttribute(required=true) annotation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM