Java JAXB Marshaller 没有值为 null 的元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18983687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 13:04:36  来源:igfitidea点击:

JAXB Marshaller does not have elements whos value is null

javaxmljaxb

提问by Rahul Agrawal

When I marshall a java object using JAXB Marshaller, the marshaller does not create empty elements for null files in the java object. For example, I have a following java object:

当我使用 JAXB Marshaller 编组 java 对象时,编组器不会为 java 对象中的空文件创建空元素。例如,我有以下 java 对象:

public class PersonTraining {

    @XmlElement(name = "Val1", required = true)
    protected BigDecimal val1;
    @XmlElement(name = "Val2", required = true, nillable = true)
    protected BigDecimal val2;
    @XmlElement(name = "Val3", required = true, nillable = true)
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar val3;
}

When I take an instance of this object, and marshall into an XML, I get the following (This is beacuse I did not set the value for Val2):

当我获取此对象的一个​​实例并将其编组为 XML 时,我得到以下信息(这是因为我没有为 Val2 设置值):

<PersonTraining>
      <Val1>1</Val1>
       <Val3>2010-01-01T00:00:00.0-05:00</Val3>
 </PersonTraining>

However, I had expected hte following result from the marshalling operation (Infact, I specifically need element as well so that the XML can be validated against the XSD)

但是,我曾期望从编组操作中获得以下结果(事实上,我还特别需要元素,以便可以针对 XSD 验证 XML)

<PersonTraining>
      <Val1>1</Val1>
      <Val2></Val2>
       <Val3>2010-01-01T00:00:00.0-05:00</Val3>
 </PersonTraining>

Please let me know what option I would need to set so that the null value in the object attributes can ALSO be marshalled, and returned as empty/null elements.

请让我知道我需要设置什么选项,以便对象属性中的空值也可以被编组,并作为空/空元素返回。

Here is the marshalling code:

这是编组代码:

StringWriter sw = new StringWriter();
JAXBContext jc = JAXBContext.newInstance("person_training");   
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(ptl, sw);

采纳答案by bdoughan

By default a JAXB (JSR-222)implementation will not marshal an attribute/element for null values. This will be true for the following field in your Java model.

默认情况下,JAXB (JSR-222)实现不会为空值封送属性/元素。这将适用于 Java 模型中的以下字段。

@XmlElement(name = "Val1", required = true)
protected BigDecimal val1;

You can override this behaviour by specifying nillable=trueon the @XmlElementannotation like you have done here:

您可以通过nillable=true@XmlElement注释上指定来覆盖此行为,就像您在此处所做的那样:

@XmlElement(name = "Val2", required = true, nillable = true)
protected BigDecimal val2;

This will cause the xsi:nil="true"attribute to be leverage:

这将导致xsi:nil="true"属性成为杠杆:

<Val2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>

For more information:

想要查询更多的信息:



Java Model

Java模型

PersonTraining

人员培训

Since you are annotating the fieldsyou should make sure you specify @XmlAccessorType(XmlAccessType.FIELD)at the class or package level (see: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html).

由于您正在注释,fields您应该确保@XmlAccessorType(XmlAccessType.FIELD)在类或包级别指定(请参阅:http: //blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html)。

import java.math.BigDecimal;
import javax.xml.bind.annotation.*;
import javax.xml.datatype.XMLGregorianCalendar;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class PersonTraining {

    @XmlElement(name = "Val1", required = true)
    protected BigDecimal val1;
    @XmlElement(name = "Val2", required = true, nillable = true)
    protected BigDecimal val2;
    @XmlElement(name = "Val3", required = true, nillable = true)
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar val3;

}

Demo Code

演示代码

Demo

演示

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(PersonTraining.class);

        PersonTraining pt = new PersonTraining();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(pt, System.out);
    }

}

Output

输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<personTraining>
    <Val2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
    <Val3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</personTraining>