如何使用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元素属性,因为nil
和empty
元素之间的差异在XML
很重要。 即xsi:nil=true
类似于SQL NULL
但具有空元素表示空元素的呈现。 🙂
我知道这很令人困惑。
要修复您的特定问题,如果您使用JAXB
序列化来生成它,我建议您阅读如何使用JAXB
实例化一个空元素 。 问题本身向您展示了如何生成空元素。
我投了gbvb的答案。
我不明白你为什么要这样呢。
xmlns:xsi
和xsi:nil
的空元素是正确的方法。
没有这些属性, even if the element is self-closed
任何reasonable
解析器都会给你空字符串。
假设你想给客户一个整数值,这意味着许多玩家得分最高。
当你可以计算出你可以给出正确的价值。 当没有玩家实际得分时,你应该将正确的值设为NULL
或nil
,这意味着没有累积的记录。
98
可以说最高分是128次尝试中的98次。
和
可以说没有最高分,因为没有记录分数。
但
除了一个简单的自闭空元素外,没有任何意义。