如何使用 JAXB 将空值表示为空元素? [英] How to represent null value as empty element with JAXB?

查看:89
本文介绍了如何使用 JAXB 将空值表示为空元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的XSD结构如下:-

<element name="XYZDate" maxOccurs="1" minOccurs="1" nillable="true" type="date"/>

当我在该字段中设置空值时,它允许我但是在 XMLJAXB 生成时,它会使用

When I set the null value in this field it allow me but at he time of XML Generation from JAXB marshaling it produce the output with

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

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

Whereas in the result I want the out put as <XYZDate/> i.e. do not want the schema and other attribute.
I get rid of this with the help of using XMLStreamWriter but it produce the complete XML in Single line. I need formatted well formed XML. If I need to use IndentingXMLStreamWriter my Java version do not support it and I do not have control over Java Container to change or modify.

请提出任何解决方案以形成 XML 格式良好.

Please suggest any solution to form XML Well Formatted.

推荐答案

注意 #1: 我是 EclipseLink JAXB (MOXy) 负责人和 <的成员strong>JAXB (JSR-222) 专家组.

NOTE #1: I am the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

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

NOTE #2: The output that you are seeing matches what you have mapped with JAXB. For more information see:

将 NULL 表示为空元素

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

If you want to represent null as an empty element, there are a couple of options.

选项 #1 - 使用标准 JAXB API

DateAdapter

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

You could use an XmlAdapter to change the way an instance of Date is marshalled to XML. We will convert the date to an instance of a class that has one property mapped with @XmlValue (see http://blog.bdoughan.com/2011/06/jaxb-and-complex-types-with-simple.html). The JAXB RI does not call the XmlAdapter mechanism for null values, so you will need to use a JAXB impl that does such as MOXy.

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

}

根目录

使用 @XmlJavaTypeAdapter 注释引用 XmlAdapter.

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

}

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

MOXy 提供了一个 @XmlNullPolicy 扩展,让您可以灵活地表示 null.

MOXy offers an @XmlNullPolicy extension that gives you some flexibility in how you represent 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;
    }

}


其他文件

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

The following files can be used with either option to complete the example.

jaxb.properties

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

To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html).

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

演示

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);
    }

}

输出

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>

这篇关于如何使用 JAXB 将空值表示为空元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆