如何用JAXB将空值表示为空元素?

Ami*_*ang 8 java xml jaxb

我的XSD结构如下: -

<element name="XYZDate" maxOccurs="1" minOccurs="1" nillable="true" type="date"/>
Run Code Online (Sandbox Code Playgroud)

当我在这个字段中设置空值时,它允许我,但是在编组时它XMLJAXB编组时产生输出

<XYZDate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
Run Code Online (Sandbox Code Playgroud)

而在结果中我想要输出,<XYZDate/>即不想要架构和其他属性.
我在使用的帮助下摆脱了这一点,XMLStreamWriter但它产生了XML单线完整.我需要格式化良好XML.如果我需要使用IndentingXMLStreamWriter我的Java版本,则不支持它,我无法控制Java容器进行更改或修改.

请建议任何形成XMLWell Formatted的解决方案.

bdo*_*han 15

注1: 我是EclipseLink JAXB(MOXy)的负责人,也是JAXB(JSR-222)专家组的成员.


注意#2: 您看到的输出与您使用JAXB映射的内容相匹配.有关更多信息,请参阅


将NULL表示为空元素

如果要将null表示为空元素,则有几个选项.

选项#1 - 使用标准JAXB API

DateAdapter

您可以使用a XmlAdapter来更改Date编组为XML 的实例的方式.我们将日期转换为具有映射的一个属性的类的实例@XmlValue(请参阅http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html).JAXB RI不会XmlAdapter为空值调用机制,因此您需要使用诸如MOXy之类的JAXB impl.

package forum11743306;

import javax.xml.bind.annotation.XmlValue;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateAdapter extends XmlAdapter<DateAdapter.AdaptedDate, XMLGregorianCalendar>{

    @Override
    public AdaptedDate marshal(XMLGregorianCalendar date) throws Exception {
        AdaptedDate adaptedDate = new AdaptedDate();
        adaptedDate.value = date;
        return adaptedDate;
    }

    @Override
    public XMLGregorianCalendar unmarshal(AdaptedDate adaptedDate) throws Exception {
        return adaptedDate.value;
    }

    public static class AdaptedDate {
        @XmlValue
        public XMLGregorianCalendar value;
    }

}
Run Code Online (Sandbox Code Playgroud)

XmlAdapter使用引用的@XmlJavaTypeAdapter注释.

package forum11743306;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlRootElement
public class Root {

    private XMLGregorianCalendar xyzDate;

    @XmlElement(name = "XYZDate", required=true, nillable = true)
    @XmlJavaTypeAdapter(DateAdapter.class)
    public XMLGregorianCalendar getXyzDate() {
        return xyzDate;
    }

    public void setXyzDate(XMLGregorianCalendar xyzDate) {
        this.xyzDate = xyzDate;
    }

}
Run Code Online (Sandbox Code Playgroud)

选项#2 - 使用MOXy的@XmlNullPolicy扩展

MOXy提供了一个@XmlNullPolicy扩展,为您提供表示null的灵活性.

package forum11743306;

import javax.xml.bind.annotation.*;
import javax.xml.datatype.XMLGregorianCalendar;

import org.eclipse.persistence.oxm.annotations.*;

@XmlRootElement
public class Root {

    private XMLGregorianCalendar xyzDate;

    @XmlElement(name = "XYZDate", required=true, nillable = true)
    @XmlNullPolicy(emptyNodeRepresentsNull = true, nullRepresentationForXml = XmlMarshalNullRepresentation.EMPTY_NODE)
    public XMLGregorianCalendar getXyzDate() {
        return xyzDate;
    }

    public void setXyzDate(XMLGregorianCalendar xyzDate) {
        this.xyzDate = xyzDate;
    }

}
Run Code Online (Sandbox Code Playgroud)

其他文件

以下文件可与任一选项一起使用以完成该示例.

jaxb.properties

要将MOXy指定为JAXB提供程序,您需要jaxb.properties在与域模型相同的程序包中包含一个名为的文件,并带有以下条目(请参阅:http: //blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as -your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Run Code Online (Sandbox Code Playgroud)

演示

package forum11743306;

import javax.xml.bind.*;
import javax.xml.datatype.DatatypeFactory;

import org.eclipse.persistence.Version;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);
        System.out.println(Version.getVersion());
        System.out.println(jc.getClass());

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        Root root = new Root();
        root.setXyzDate(null);
        marshaller.marshal(root, System.out);

        root.setXyzDate(DatatypeFactory.newInstance().newXMLGregorianCalendar("2012-08-01"));
        marshaller.marshal(root, System.out);
    }

}
Run Code Online (Sandbox Code Playgroud)

产量

2.4.0
class org.eclipse.persistence.jaxb.JAXBContext
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <XYZDate/>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <XYZDate>2012-08-01</XYZDate>
</root>
Run Code Online (Sandbox Code Playgroud)


小智 4

您应该阅读nillable 和 minOccurs XSD 元素属性nil,因为和元素之间的差异emptyXML. iexsi:nil=true与 类似,SQL NULL但具有空元素表示空元素的呈现。:)
我知道这很令人困惑。

要解决您的特定问题,如果您使用JAXB序列化来生成该问题,我建议阅读如何使用 JAXB 实例化空元素。问题本身向您展示了如何生成空元素。