JAXB sort boolean into complex type
I'm new to JAXB and I would like to do something that I don't know if it is doable. I have a java class for sorting like this:
@XmlAccessorType(XMLAccessType.NONE)
public class MyClass {
@XmlElement
private String a = "x";
@XmlElement
private String b = "xx";
@XmlElement
private boolean c = true;
...
}
and want the XML output to look like this:
<?xml ...?>
<MyClass>
<a>x</a>
<b>xx</b>
<c value="true"/>
</MyClass>
One solution I have in mind is to use the boolean class to make it work, but I would like to avoid that as it takes me away from using the boolean primitive true, false.
Can we do this in JAXB?
source to share
Shoulder An XmlAdapter
You can create XmlAdapter
to get the behavior you are looking for. XmlAdapter
converts a domain object to another type for marshalling and stripping purposes.
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class BooleanAdapter extends XmlAdapter<BooleanAdapter.AdaptedBoolean, Boolean> {
public static class AdaptedBoolean {
@XmlAttribute
public boolean value;
}
@Override
public Boolean unmarshal(AdaptedBoolean adaptedBoolean) throws Exception {
return adaptedBoolean.value;
}
@Override
public AdaptedBoolean marshal(Boolean v) throws Exception {
AdaptedBoolean adaptedBoolean = new AdaptedBoolean();
adaptedBoolean.value = v;
return adaptedBoolean;
}
}
Using XmlAdapter
To use XmlAdapter
, your display field must be of type Boolean
instead of Boolean
. If you want, you can use the access methods Boolean
.
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlAccessorType(XmlAccessType.NONE)
public class MyClass {
@XmlElement
private String a = "x";
@XmlElement
private String b = "xx";
@XmlElement
@XmlJavaTypeAdapter(BooleanAdapter.class)
private Boolean c = true;
public boolean getC() {
return c;
}
public void setC(boolean c) {
this.c = c;
}
}
source to share
The XML output of your class:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myClass>
<a>x</a>
<b>xx</b>
<c>true</c>
</myClass>
If you want the value to boolean
get
<c value="true" />
then you need a wrapping element around the box boolean c
. It can be a type boolean
or some other custom type with boolean c
inside it and tagged @XmlAttribute
.
Example:
class MyBool {
@XmlAttribute(name="value")
private boolean c = true;
}
@XmlAccessorType(XmlAccessType.NONE)
class MyClass {
@XmlElement
private String a = "x";
@XmlElement
private String b = "xx";
@XmlElement
private MyBool c = new MyBool();
}
Output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myClass>
<a>x</a>
<b>xx</b>
<c value="true"/>
</myClass>
Note:
If you don't want to use a wrapper, you can annotate boolean c
with @XmlAttribute
like this:
@XmlAttribute(name="value")
private boolean c = true;
But then it will show up as an attribute of the wrapper class which is equal in this case MyClass
, so the output will be:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myClass value="true">
<a>x</a>
<b>xx</b>
</myClass>
source to share