我正在使用JAXB来编组和解组java类。
这是我正在寻找的xml:
<tag name="example" attribute1="enumValue"/>
如果attribute1设置为默认值,我根本不想打印该属性,所以它看起来像这样:
<tag name="example"/>
有没有办法做到这一点?
现在我有一个看起来像这样的getter / setter对:
@XmlAttribute(name="attribute1")
public EnumExample getEnumExample() {
return this.enumExample;
}
public void setEnumExample(final EnumExample enumExample) {
this.enumExample = enumExample;
}
答案 0 :(得分:5)
您可以在此用例中使用XmlAdapter
:
XmlAdapter(Attribute1Adapter)
您可以利用以下事实:JAXB不会封送空属性值,并使用XmlAdapter
来调整正在编组为XML的值。
import javax.xml.bind.annotation.adapters.XmlAdapter;
import forum16972549.Tag.Foo;
public class Attribute1Adapter extends XmlAdapter<Tag.Foo, Tag.Foo>{
@Override
public Foo unmarshal(Foo v) throws Exception {
return v;
}
@Override
public Foo marshal(Foo v) throws Exception {
if(v == Foo.A) {
return null;
}
return v;
}
}
域名模型(标记)
@XmlJavaTypeAdapter
注释用于关联XmlAdapter
。
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Tag {
enum Foo {A, B};
@XmlAttribute
@XmlJavaTypeAdapter(Attribute1Adapter.class)
private Foo attribute1;
public Foo getAttribute1() {
return attribute1;
}
public void setAttribute1(Foo attribute1) {
this.attribute1 = attribute1;
}
}
<强>演示强>
下面是一些可用于证明一切正常的演示代码。
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Tag.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Tag tag = new Tag();
tag.setAttribute1(Tag.Foo.A);
System.out.println(tag.getAttribute1());
marshaller.marshal(tag, System.out);
tag.setAttribute1(Tag.Foo.B);
System.out.println(tag.getAttribute1());
marshaller.marshal(tag, System.out);
}
}
<强>输出强>
以下是运行演示代码的输出。
A
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tag/>
B
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tag attribute1="B"/>
答案 1 :(得分:2)
代码强>
您可以利用以下事实:JAXB不会封送空属性值并向您的属性添加一些逻辑,然后使用JAXB映射到该字段。
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Tag {
private static Foo ATTRIBUTE1_DEFAULT = Foo.A;
enum Foo {A, B};
@XmlAttribute
private Foo attribute1;
public Foo getAttribute1() {
if(null == attribute1) {
return ATTRIBUTE1_DEFAULT;
}
return attribute1;
}
public void setAttribute1(Foo attribute1) {
if(ATTRIBUTE1_DEFAULT == attribute1) {
this.attribute1 = null;
} else {
this.attribute1 = attribute1;
}
}
}
<强>演示强>
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Tag.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Tag tag = new Tag();
tag.setAttribute1(Tag.Foo.A);
System.out.println(tag.getAttribute1());
marshaller.marshal(tag, System.out);
tag.setAttribute1(Tag.Foo.B);
System.out.println(tag.getAttribute1());
marshaller.marshal(tag, System.out);
}
}
<强>输出强>
A
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tag/>
B
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tag attribute1="B"/>
答案 2 :(得分:1)
AFAIK,这不可能直接使用JAXB注释。但是像这样使用 required = true ,
@XmlAttribute(required=true name="attribute1")
private String enumExample;
我们可以做一个解决方法。在调用该属性的setter之前,我们可以检查将要设置的值是否为默认值。如果是,我们可以将null传递给该setter,并且在编组后该属性将不可见。