Java JAXB:如果有特殊值(例如`null`或`Double.NaN`),则忽略元素序列化

Java JAXB:如果有特殊值(例如`null`或`Double.NaN`),则忽略元素序列化,java,xml,serialization,jaxb,Java,Xml,Serialization,Jaxb,我想用JAXB序列化一个Java对象。对象具有可能具有特殊值的实例变量,例如null或在另一种情况下Double.NaN 如果实例变量有这个特殊值,我怎么能只忽略它呢 这可能吗 MWE 因此,如果value为Double.NaN且object不为null,我希望 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <MyClass> <object> ... </object&g

我想用
JAXB
序列化一个Java对象。对象具有可能具有特殊值的实例变量,例如
null
或在另一种情况下
Double.NaN

如果实例变量有这个特殊值,我怎么能只忽略它呢

这可能吗


MWE 因此,如果
value
Double.NaN
object
不为
null
,我希望

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MyClass>
  <object>
    ...
  </object>
</MyClass>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MyClass>
  <value>1.0</value>
</MyClass>

默认情况下,Null值不会生成XML,因此您对
对象
属性的要求已经得到处理

对于特殊的
double
值,创建一个专门的方法来生成XML
值,并抑制
getValue()
到XML的正常映射

这可以通过使用注释或使用禁用自动特性选择来实现,因此只有带注释的特性才会映射到XML

下面是使用第二种方法的示例:

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class MyClass {

    private double value;
    private Foo foo;

    public MyClass() {
    }
    public MyClass(double value, Foo foo) {
        this.value = value;
        this.foo = foo;
    }

    public void setValue(double value){this.value = value;}
    public double getValue(){return this.value;}

    public void setFoo(Foo foo){this.foo = foo;}
    @XmlElement() public Foo getFoo(){return this.foo;}

    @XmlElement(name = "value")
    public Double getXmlValue() {
        if (Double.isFinite(this.value))
            return this.value;
        return null;
    }
}

public class Foo {
    @XmlElement()
    public String getBar() { return "Test"; }
}
试验

输出


3.141592653589793
测验
请注意,第一个值缺少
,因为它是
null
,第二个值缺少
,因为
NaN
值作为
null
值返回

调用
getValue()
时,正常使用
MyClass
仍将获得
NaN

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class MyClass {

    private double value;
    private Foo foo;

    public MyClass() {
    }
    public MyClass(double value, Foo foo) {
        this.value = value;
        this.foo = foo;
    }

    public void setValue(double value){this.value = value;}
    public double getValue(){return this.value;}

    public void setFoo(Foo foo){this.foo = foo;}
    @XmlElement() public Foo getFoo(){return this.foo;}

    @XmlElement(name = "value")
    public Double getXmlValue() {
        if (Double.isFinite(this.value))
            return this.value;
        return null;
    }
}

public class Foo {
    @XmlElement()
    public String getBar() { return "Test"; }
}
JAXBContext jaxbContext = JAXBContext.newInstance(MyClass.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

marshaller.marshal(new MyClass(Math.PI, null), System.out);
marshaller.marshal(new MyClass(Double.NaN, new Foo()), System.out);