JAXB - Controlling element names for lists inside wrapper class - java

I have a class wrapping up a list and some other attribute and in another class I have multiple instances of the wrapper type. I know that we can control the name of elements by adding XmlElement annotation to whichever element we need. Is there any way to specify the element name corresponding to the contents of a wrapper type from wherever the wrapper type is used?
For instance, the wrapper class looks like
#XmlAccessorType(XmlAccessType.FIELD)
public class Wrapper {
#XmlElement(name = "name")
private List<String> names;
private String comment;
//Getters and setters
}
And the wrapper is used as
private Wrapper employeeNames;
private Wrapper departmentNames;
private Wrapper someOtherNames;
Can I in someway annotate these fields, so that I would have XML formed as
<employeeNames>
<employeeName>ABC DEF</employeeName>
<employeeName>PQR STU</employeeName>
<employeeName>ABC</employeeName>
</employeeNames>
<departmentNames>
<departmentName>PQR</departmentName>
<departmentName>PQR STU</departmentName>
<departmentName>MNO</departmentName>
</departmentNames>
I know that if don't have the wrapper and directly use the lists, I can have #XmlElementWrapper and #XmlElement annotations used to build the XML like this.

You could try this:
#XmlAccessorType(XmlAccessType.FIELD)
public class Wrapper {
#XmlElements({
#XmlElement(name = "employeeName", type = EmployeeName.class),
#XmlElement(name = "departmentName", type = DepartmentName.class),
})
private List<Name> names;
private String comment;
public void setNames(List<Name> names) {
this.names = names;
}
}
and then EmployeeName and DepartmentName something like this:
#XmlAccessorType(XmlAccessType.FIELD)
public class EmployeeName implements Name {
#XmlValue
private String name;
public EmployeeName(String name) {
this.name = name;
}
}
They both implement an interface that doesn't do much:
public interface Name { }
I changed your List<String> to List<Name> in your wrapper, because the marshaling would have problem to differentiate between employeeName and departmentName if they both were of type String.

The only thing that comes to mind is that instead of #XmlElement you could use #XmlElementRef like
#XmlElementRef(name = "name")
private List<JAXBElement<String>> names;
Then you could specify the desired element name in each of the elements of names:
wrapper.names.add(new QName("departmentName"), String.class, "PQR");

Related

How to unmarshal array or list using JAXB?

I have an XML file and I need to set it up with my POJO class
<ids xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays" >
<a:string>100</a:string>
<a:string>101</a:string>
<a:string>102</a:string>
... etc..
</ids>
Which annotation do I have to use, to fetch these values
I am using the following way.
#XmlElement(name="string",namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays")
protected List<String> id;
but I am getting null
You did not present the class containing protected List<String> id. It should be something like
#XmlRootElement(name = "ids")
public class Wrapper {
#XmlElement(name = "string",
namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")
protected List<String> id;
}
to have the list populated. Also you can name the class Ids and remove name = 'Ids'.

Right annotations to a list<String> JAXB

I searched and saw many questions with similiar scanerios yet i couldnt make my solution work
I want a simple object to be converted into XML using JAXB.
My problem is i have an arrayList as one of my properties and i just cant find the right annotation to go with it.
#XmlRootElement(name = "fighter")
public class fighter{
private int health;
private int energy;
private String name;
private List<String> abilities;
}
if i remove the abilities property i can marshall\unmarshall this class.
but when i try to do it with the abilities property its telling me i have illegal annotation
#XmlElementWrapper(name = "abilitiesList")
#XmlElement(name = "ability")
public List<String> getAbilities(){
return abilities
}
I've tried all sort of annotations but I just dont get whats wrong with it.
Thanks for the help
Try this :
#XmlRootElement(name = "fighter")
#XmlAccessorType(XmlAccessType.FIELD)
public class Fighter{
#XmlElement
private int health;
#XmlElement
private int energy;
#XmlElement
private String name;
#XmlElementWrapper(name = "abilitiesList")
#XmlElement(name = "ability")
private List<String> abilities;
}
Your getters and setters must be without JAXB annotations.
Your list of abilities will be marshalled like this :
<abilitiesList>
<ability></ability>
<ability></ability>
</abilitiesList>
If it's not working, please provide a sample of your expected XML.

JAXB - Xml Annotation in Parent class to only set a specific field in child class

Let's say we have a person who has a Child and I want to annotate the object reference to only map a specific field in the Child class to the parent object.
Which annotation will I be using then?
The xml looks like this:
<Person>
<Child>Peter</Child>
</Person>
POJOs looks like this:
public class Person {
#XmlElement(name = "Child")
private Child child;
}
public class Child {
#XmlElement(name = "Child")
private String name;
}
But this doesnt work at all, I've also tried XmlElementRef etc.
public class Child {
#XmlValue
private String name;
}

Can't parse properties of complex type

I'm working with eBay's finding service, and everything works fine except parsing unitPrice. It says here:
eBay uses the UnitType and UnitQuantity
So in my UnitPriceInfo.java I have this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "UnitPriceInfo", propOrder = { "type", "quantity", "any" })
public class UnitPriceInfo
{
#XmlElement(name = "UnitType")
protected String type;
#XmlElement(name = "UnitQuantity")
protected Double quantity;
#XmlAnyElement(lax = true)
protected List<Object> any;
But still, UnitPriceInfo objects are instantiated but they always have both type and quantity fields to null.
Do I need to change the type from String and Double to UnitType and UnitQuantity? If not, what's the problem?
The elements are named type and quantity, like this:
<unitPrice>
<quantity> double </quantity>
<type> string </type>
</unitPrice>
You should change your annotations to #XmlElement(name="type") and #XmlElement(name="quantity").
can you please change class name from UnitPriceInfo to "unitPrice" OR give annotated name "unitPrice" for class name .

Json - replace field name in generic Dto with associated type name

I have DTO class with Generics for data transfer
public class CreateDto<E> {
private String id;
private String name;
private E e;
}
My problem is while converting object to json using ObjectMapper, I am always getting json string as
{id : 1, name : 2, e : {"state1":"value1" ...} };
I want that e to be replaced with specific thing like, if it CreateDto<Foo> I want it like a foo:{"state1":"value1" ..}, when it is CreateDto it should be bar : {"state2":"value2"..}
I would like to know whether is there a way to get this using annotation or some other util.
Thought, this is not the same way as you required, the same principal is to use #JsonTypeInfo annotation at the property or method (getter or setter) level.
The following example (at property level);
public class CreateDto<E> {
private String id;
private String name;
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type")
private E e;
...
}
will produce json string (e.g Foo for E)
{"id":"100","name":"john","e":{"type":"Foo","state1":"value1"...}}
Now it is distinct on the underlying type in generic data transfer object.

Categories