3

我试图在 spring beans 配置文件中配置一个 jaxb2Marshaller,但我对 Spring 和 JAXB 很陌生,所以我可能会以错误的方式去做。

我想要实现的是同一个 bean,它将编组/解组基于 2 个不同模式的 2 个不同类。也许那是不可能的,因为当我配置并运行我的测试时,它们在配置中的第二类(AccountResponse)中失败了。

这是 XML 配置:

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

如果我从配置中注释掉AccountRequest.xsd值,然后再次运行我的测试,第二类 (AccountResponse) 的编组/解组,它们都通过了,如果我取消注释它,我得到错误:org.xml.sax.SAXParseException :cvc-elt.1:找不到元素“accountResponse”的声明。

我是不是走错路了?难道不能用两个模式处理两个类吗?

谢谢,约夫。

4

2 回答 2

5

“如果我从配置中注释掉 AccountRequest.xsd 值,然后再次运行我的测试,则第二类 (AccountResponse) 的编组/解编组都通过了,如果我取消注释它,我会收到错误:org.xml.sax。 SAXParseException:cvc-elt.1:找不到元素“accountResponse”的声明。”

听起来 SchemaFactory.newSchema() 创建的 Schema 对象只处理列表中的第一个 xsd。

如果您在同一个命名空间(targetNamespace?)中有多个模式文件,那么可能是这个错误导致了麻烦:

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

我为解决这个错误所做的工作是创建一个包含其他 xsd 文件的父 xsd 文件,然后使用 LSResourceResolver 实现在 xml 配置中设置“schemaResourceResolver”属性(参见http://blog.frankel.ch/xml-验证-with-importedincluded-schemas例如)..

在您的 xml 配置中添加以下内容:

parent.xsd 文件如下所示:

<?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>

在您的 xml 配置中,将 schemas 属性更改为:

<property name="schemas">
        <list>
        <value>classpath:schema/parent.xsd</value>
        </list>
</property>
于 2013-07-29T07:40:56.993 回答
1

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.

于 2012-05-30T21:47:04.300 回答