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

我的XSD结构如下: –

  

当我在这个字段中设置空值时,它允许我,但是在他从JAXB编组的XML生成时,它产生输出

  

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

请建议任何形成XML Well Formatted的解决方案。

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


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


将NULL表示为空元素

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

选项#1 – 使用标准JAXB API

DateAdapter

您可以使用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{ @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批注引用@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; } } 

选项#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; } } 

其他文件

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

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 

演示

 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       2012-08-01  

您应该读取nillable和minOccurs XSD元素属性,因为nilempty元素之间的差异在XML很重要。 即xsi:nil=true类似于SQL NULL但具有空元素表示空元素的呈现。 🙂
我知道这很令人困惑。

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

我投了gbvb的答案。

我不明白你为什么要这样呢。

xmlns:xsixsi:nil的空元素是正确的方法。

没有这些属性, even if the element is self-closed任何reasonable解析器都会给你空字符串。

假设你想给客户一个整数值,这意味着许多玩家得分最高。

当你可以计算出你可以给出正确的价值。 当没有玩家实际得分时,你应该将正确的值设为NULLnil ,这意味着没有累积的记录。

 98 

可以说最高分是128次尝试中的98次。

  

可以说没有最高分,因为没有记录分数。

  

除了一个简单的自闭空元素外,没有任何意义。