1

我想使用 Spring Batch (JAXB2Marshaller) 生成 XML 文件,但我在下面的问题上坚持了 1 周,在此先感谢。

预期的 xml

<?xml version="1.0" encoding="UTF-8"?>
<p:ContactList xmlns:p="test:ns:2012">
  <p:CompanyInfo>
    <p:CompanyName>Oracle</p:CompanyName>
    <p:DepartmentInfo>
      <p:DepartmentName>Java</p:DepartmentName>
    </p:DepartmentInfo>
  </p:CompanyInfo>
</p:ContactList>

但我得到了

<?xml version="1.0" encoding="UTF-8"?>
<ContactList>
  <p:CompanyInfo xmlns:p="test:ns:2012">
    <p:CompanyName xmlns:p="test:ns:2012">Oracle</p:CompanyName>
    <p:DepartmentInfo xmlns:p="test:ns:2012">
      <p:DepartmentName xmlns:p="test:ns:2012">Java</p:DepartmentName>
    </p:DepartmentInfo>
  </p:CompanyInfo>
</ContactList>

下面是源代码

弹簧配置

<bean id="itemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
  <property name="resource" ref="outputResource" />
  <property name="marshaller" ref="myMarshaller" />
  <property name="rootTagName" value="ContactList" />
  <property name="overwriteOutput" value="true" />
</bean>

<bean id="myMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="contextPaths">
        <list>
            <value>org.springframework.batch.contactlist</value>
        </list>
    </property>
    <property name="marshallerProperties">
        <map>
             <entry key="jaxb.formatted.output"><value type="boolean">true</value></entry>
       </map>
    </property>
      <property name="supportJaxbElementClass" value="true"/>
</bean>

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="test:ns:2012" targetNamespace="test:ns:2012" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="ContactList" type="ContactList"/>
    <xs:complexType name="ContactList">
        <xs:sequence>
            <xs:element maxOccurs="unbounded" minOccurs="1" name="CompanyInfo" type="CompanyInfo"/>
        </xs:sequence>
    </xs:complexType>
  <xs:complexType name="CompanyInfo">
    <xs:sequence>
      <xs:element name="CompanyName" type="CompanyName" minOccurs="0"/>
      <xs:element name="DepartmentInfo" type="DepartmentInfo"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="DepartmentInfo">
    <xs:sequence>
      <xs:element name="DepartmentName" type="DepartmentName"/>
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="CompanyName">
    <xs:restriction base="xs:string">
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="DepartmentName">
    <xs:restriction base="xs:string">
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

包信息.java

@javax.xml.bind.annotation.XmlSchema(namespace = "test:ns:2012", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
xmlns={@XmlNs(prefix="p", namespaceURI="test:ns:2012")})
package org.springframework.batch.contactlist;
import javax.xml.bind.annotation.XmlNs;

对象工厂.java

@XmlRegistry
public class ObjectFactory {
    @XmlElementDecl(name = "CompanyInfo")
    public JAXBElement<CompanyInfo> createContactList(CompanyInfo value) {
        return new JAXBElement<CompanyInfo>(null, CompanyInfo.class, null, value);
    }
}

公司信息.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="CompanyInfo")
@XmlType(name = "CompanyInfo", propOrder = {
    "companyName",
    "departmentInfo"
})
public class CompanyInfo {
    @XmlElement(name = "CompanyName")
    protected String companyName;
    @XmlElement(name = "DepartmentInfo", required = true)
    protected DepartmentInfo departmentInfo;
}

部门信息.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "DepartmentInfo", propOrder = {
    "departmentName"
})
public class DepartmentInfo {

    @XmlElement(name = "DepartmentName", required = true)
    protected String departmentName;
}
4

1 回答 1

0

通过在 NamespacePrefixMapper 中添加 getContextualNamespaceDecls() 解决了问题

@Override
public String[] getContextualNamespaceDecls() {
    return new String[] {"p", "test-ns-2012" };
}
于 2013-01-01T14:41:27.157 回答