所有子元素都用命名空间标记[Spring Batch& JAXB]

时间:2012-12-30 14:00:42

标签: jaxb spring-batch

我想使用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>

以下是源代码

Spring Config

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

package-info.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;

ObjectFactory.java

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

CompanyInfo.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;
}

DepartmentInfo.java

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

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

1 个答案:

答案 0 :(得分:0)

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

@Override
public String[] getContextualNamespaceDecls() {
    return new String[] {"p", "test-ns-2012" };
}