Reg:Jaxb
我基本上试图在JAXB中设置一个角色,它表示只要遇到空字段,而不是在输出中忽略它,就把它设置为空值。
对于xmlElement,我得到了答案,就像我们需要使用nillable =“true”但是我们需要如何设置null值。通过谷歌搜索我发现我们需要使用use =“optional”但它不适用于我的情况。
我的xsd部分如下:
<xs:attribute name="RomVersion" type="xs:string" use="required" />
<xs:attribute name="MACAddress" type="xs:string" use="required" />
<xs:attribute name="LargestFreeBlock" type="xs:unsignedInt" use="required" />
<xs:attribute name="TimeSinceLastReset" type="xs:unsignedInt" use="optional" />
<xs:attribute name="ResetReason" type="xs:string" use="optional" />
<xs:attribute name="TimeStamp" type="xs:unsignedInt" use="optional" />
<xs:attribute name="ECOList" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
如果有人知道,请尽快给我解决方案。
答案 0 :(得分:6)
从XML架构开始
在previous answer中,我描述了从Java对象开始时如何解决用例。根据您对该答案的评论,这个答案描述了当从XML模式生成模型时,如何做同样的事情。
XML架构(attributeAdapter.xsd)
对于此示例,我们将使用以下XML架构:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
elementFormDefault="qualified"
targetNamespace="http://www.example.com/adapter"
xmlns:nytd="http://www.example.com/adapter"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:attribute name="foo" type="xs:string"/>
<xs:attribute name="bar" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:schema>
<强> 字符串转换 强>
我们需要定义一个类来进行特殊的字符串处理。对于此用例,我们希望在XML文档中将空字段/属性值视为空字符串(“”):
package com.example.adapter;
public class StringConverter {
public static String parseString(String value) {
if("".equals(value)) {
return null;
}
return value;
}
public static String printString(String value) {
if(null == value) {
return "";
}
return value;
}
}
绑定文件(attributeAdapterBinding.xml)
我们需要使用JAXB绑定文件来自定义类生成。下面的绑定文件将允许我们利用上面定义的StringConverter类:
<jaxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="attributeAdapter.xsd">
<jaxb:bindings node="//xs:element[@name='root']/xs:complexType">
<jaxb:bindings node="xs:attribute[@name='foo']">
<jaxb:property>
<jaxb:baseType>
<jaxb:javaType name="java.lang.String"
parseMethod="com.example.adapter.StringConverter.parseString"
printMethod="com.example.adapter.StringConverter.printString"/>
</jaxb:baseType>
</jaxb:property>
</jaxb:bindings>
<jaxb:bindings node="xs:attribute[@name='bar']">
<jaxb:property>
<jaxb:baseType>
<jaxb:javaType name="java.lang.String"
parseMethod="com.example.adapter.StringConverter.parseString"
printMethod="com.example.adapter.StringConverter.printString"/>
</jaxb:baseType>
</jaxb:property>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
XJC致电
我们将按如下方式拨打XJC电话:
xjc -d out -b attributeAdapterBinding.xml attributeAdapter.xsd
域模型(根)
我们在绑定文件中自定义的字段/属性将使用@XmlJavaTypeAdapter进行注释;
package com.example.adapter;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "root")
public class Root {
@XmlAttribute
@XmlJavaTypeAdapter(Adapter1 .class)
protected String foo;
@XmlAttribute
@XmlJavaTypeAdapter(Adapter2 .class)
protected String bar;
public String getFoo() {
return foo;
}
public void setFoo(String value) {
this.foo = value;
}
public String getBar() {
return bar;
}
public void setBar(String value) {
this.bar = value;
}
}
XmlAdapter(Adapter1)
生成的XmlAdapter类将如下所示。请注意它如何利用我们的StringConverter类:
package com.example.adapter;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class Adapter1 extends XmlAdapter<String, String> {
public String unmarshal(String value) {
return (com.example.adapter.StringConverter.parseString(value));
}
public String marshal(String value) {
return (com.example.adapter.StringConverter.printString(value));
}
}
<强> 演示 强>
现在,如果我们运行以下演示代码:
package com.example.adapter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Root root = new Root();
root.setFoo(null);
root.setBar(null);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
<强> 输出 强>
我们将获得所需的输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://www.example.com/adapter" foo="" bar=""/>
更新(替代绑定文件)
或者,如果您希望将适配器应用于类型xsd:string
的所有属性,那么您可以使用看起来类似的绑定文件;
<jaxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:globalBindings>
<jaxb:javaType
name="String"
xmlType="xs:string"
parseMethod="com.example.adapter.StringConverter.parseString"
printMethod="com.example.adapter.StringConverter.printString"/>
</jaxb:globalBindings>
</jaxb:bindings>
答案 1 :(得分:5)
从Java对象开始
对于映射为@XmlAttribute
的字段/属性,JAXB实现(Metro,MOXy,JaxMe等)将空字符串(“”)值封送为property=""
。您可以使用XmlAdapter
将空值公开为空字符串以获得所需的行为:
的 NullStringAdapter 强> 的
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class NullStringAdapter extends XmlAdapter<String, String> {
@Override
public String unmarshal(String v) throws Exception {
if("".equals(v)) {
return null;
}
return v;
}
@Override
public String marshal(String v) throws Exception {
if(null == v) {
return "";
}
return v;
}
}
的根强> 的
以下是如何在域模型中指定适配器。同一个适配器可用于许多属性:
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Root {
private String foo;
private String bar;
@XmlAttribute
@XmlJavaTypeAdapter(NullStringAdapter.class)
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
@XmlAttribute
@XmlJavaTypeAdapter(NullStringAdapter.class)
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
的演示强> 的
您可以通过运行以下演示代码来演示该概念:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Root root = new Root();
root.setFoo(null);
root.setBar(null);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
的输出强> 的
以下是演示代码输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root bar="" foo=""/>
有关JAXB的XmlAdapter的更多信息,请参阅:
答案 2 :(得分:0)
您可以为此使用默认值插件。
请查看以下问题:JAXB xjc: How to generate code for Strings that returns empty if the value is null?