Is it possible to ignore a wrapper class during JAXB sorting

I am trying to get JAXB to ignore the wrapper class during the Mashalling process, it makes sense to have this wrapper class in the code, since it stores all the related information together, however I need to get rid of it during the marshaling process. Below is the corresponding code.

@XmlType(name = "root") @XmlRootElement(name = "root") public class Root { @XmlElementRef private List<Resource> resources = new ArrayList<>(); public void addResource(Resource resource) { resources.add(resource); } } @XmlRootElement(name = "", namespace = "") @XmlAccessorType(XmlAccessType.NONE) public class Resource { @XmlElementRef private Element element; @XmlElementRef private FieldType fieldType; @XmlElementRef private ListType listType; } 

Root is the main object, and Resource is a wrapper object for which I would not create a node. However, I still want Element, FieldType, and ListType to appear in the Resource.

This is what I have:

 <root> <> <element name="resource1"/> <fieldType name="resource1--type"> </fieldType> <listType name="resource--list"> </listType> </> <> <element name="resource2"/> <fieldType name="resource2--type"> </fieldType> <listType name="resource2--list"> </listType> </> </root> 

I would like to get the following:

 <root> <element name="resource1"/> <fieldType name="resource1--type"> </fieldType> <listType name="resource--list"> </listType> <element name="resource2"/> <fieldType name="resource2--type"> </fieldType> <listType name="resource2--list"> </listType> </root> 

I do not know if this is possible, but any help would be appreciated.

Thanks.

+4
source share
3 answers

You cannot achieve this in JAXB. Even if you can serialize it, for example using the XmlAdapter, it cannot be deserialized.

Try the following:

 @XmlType(name = "root") @XmlRootElement(name = "root") @XmlAccessorType(XmlAccessType.NONE) public class Root { private ArrayList<Resource> resources = new ArrayList<Resource>(); public void addResource(Resource resource) { resources.add(resource); } @XmlElementRefs(value = { @XmlElementRef(type = Element.class), @XmlElementRef(type = ListType.class), @XmlElementRef(type = FieldType.class) }) public List<Object> getResourceFields() { List<Object> list = new ArrayList<Object>(); for (Resource r : resources) { list.add(r.getElement()); list.add(r.getFieldType()); list.add(r.getListType()); } return list; } } 

Basically, getRerourceFields combines all resource fields in the same list. If you can’t change the Root class, it could be your RootAdapter and use it as suggested by @Biju.

+5
source

You probably have to create an XmlAdapter for your Root class, this adapter should basically map your root instances to another type, where you can smooth your root structure before sorting - by these lines:

 public class CustomRootAdapter extends XmlAdapter<CustomRoot,Root>> { @Override public Root unmarshal(CustomRoot v) throws Exception { return null;//if you are not keen on unmarshalling.. } @Override public CustomRoot marshal(Root v) throws Exception { return ...; } 

}

You can register this custom adapter using:

@XmlJavaTypeAdapter(CustomRootAdapter.class) with your Root class

+2
source

This is similar to what @XMLTransient does.

When placed in a class, it indicates that the class should not be mapped to XML on its own. The properties of this class will be mapped to XML along with its derived classes, as if the class were inlined.

See javadoc

-1
source

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


All Articles