JAXB配置需求:生成xs:nil而非xmlns:xsi属性
JAXB生成
xs:nil="true"替代xsi:nil="true"的实现方案 要让JAXB输出带xs:nil="true"的XML元素,而非默认的xsi:nil="true",可以通过自定义XML适配器+实体类注解配置实现,具体步骤如下:
1. 编写自定义XmlAdapter
这个适配器会在字段为null时,生成带xs:nil="true"的空元素:
import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.namespace.QName; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilderFactory; public class XsNilAdapter extends XmlAdapter<Object, Object> { // 定义xs命名空间的nil属性 private static final QName XS_NIL = new QName("http://www.w3.org/2001/XMLSchema", "nil", "xs"); @Override public Object unmarshal(Object v) { // 反序列化无需特殊处理,直接返回原对象 return v; } @Override public Object marshal(Object v) throws Exception { if (v == null) { // 创建空元素并添加xs:nil="true"属性 Element emptyElement = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .newDocument() .createElement("temp"); emptyElement.setAttributeNS(XS_NIL.getNamespaceURI(), "xs:nil", "true"); return emptyElement; } return v; } }
2. 在实体类中配置适配器与命名空间
在需要生成nil的字段上绑定适配器,同时在类上声明xs命名空间:
import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement(name = "TargetElement") // 声明xs命名空间,确保前缀正确 @XmlSchema(xmlns = {@XmlNs(prefix = "xs", namespaceURI = "http://www.w3.org/2001/XMLSchema")}) public class YourEntity { private String nullableField; @XmlElement(name = "NullableField") // 绑定自定义适配器 @XmlJavaTypeAdapter(XsNilAdapter.class) public String getNullableField() { return nullableField; } public void setNullableField(String nullableField) { this.nullableField = nullableField; } }
3. 调整Marshaller配置禁用xsi命名空间
默认JAXB会自动添加xsi命名空间,需要通过命名空间映射器禁用它:
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import com.sun.xml.bind.marshaller.NamespacePrefixMapper; public class JaxbMarshallerTest { public static void main(String[] args) throws JAXBException { YourEntity entity = new YourEntity(); entity.setNullableField(null); // 设置为null触发nil生成 JAXBContext context = JAXBContext.newInstance(YourEntity.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 自定义命名空间映射,不生成xsi前缀 marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapper() { @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { if ("http://www.w3.org/2001/XMLSchema-instance".equals(namespaceUri)) { return ""; // 跳过xsi命名空间的前缀生成 } return suggestion; } }); marshaller.marshal(entity, System.out); } }
最终输出示例
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <TargetElement xmlns:xs="http://www.w3.org/2001/XMLSchema"> <NullableField xs:nil="true"/> </TargetElement>
内容的提问来源于stack exchange,提问作者Chris A
相关产品推荐
相关产品推荐

