Is there a way to indicate that JAXB should print only the attribute if it does not have a specific value?

I work with JAXB to marshal and demonstrate a java class.

This is the xml I'm looking for:

<tag name="example" attribute1="enumValue"/> 

if attribute1 is set to the default value, I do not want this attribute to be printed at all, so it will look like this:

 <tag name="example"/> 

Is there any way to do this?

Right now I have a getter / setter pair that looks like this:

 @XmlAttribute(name="attribute1") public EnumExample getEnumExample() { return this.enumExample; } public void setEnumExample(final EnumExample enumExample) { this.enumExample = enumExample; } 
+4
source share
3 answers

You can use the XmlAdapter for this use case:

XmlAdapter (attribute 1Adapter)

You could use the fact that JAXB will not march on null attribute values ​​and use the XmlAdapter to customize the value that will be bound to 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; } } 

Domain Model (tag)

The @XmlJavaTypeAdapter annotation @XmlJavaTypeAdapter used to bind the 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; } } 

Demo

Below is some demo code that you can use to prove that everything works.

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

Output

The following is the result of running the demo code.

 A <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <tag/> B <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <tag attribute1="B"/> 
+5
source

Tag

You can use the fact that JAXB will not march on null attribute values ​​and add some logic to your properties, and then use JAXB to display in the field.

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

Demo

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

Output

 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
source

AFAIK, this is not possible directly with JAXB annotations. But using required = true like this,

 @XmlAttribute(required=true name="attribute1") private String enumExample; 

we can make a workaround. Before calling the installer for this attribute, we can check whether the value that will be set is the default value. If so, we can pass null to this setter, and this attribute will not be displayed after sorting.

+1
source

Source: https://habr.com/ru/post/1484923/


All Articles