2

I have a Response class which contains some basic attributes and a wildcard Collection<?>.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {
    private String approved;
    private String errorCode;
    @XmlAnyElement(lax = true)
    private Collection<?> collection;

    public Response() {
    }

    public Response(String approved, Collection<?> collection) {
        this.approved = approved;
        this.collection = collection;
    }

    public String getApproved() {
        return approved;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public Collection<?> getCollection() {
        return collection;
    }
}

This collection can contain many types, for example this type:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Transaction {
    private BigDecimal amount;
    private String transactionId;

    public Transaction(BigDecimal amount, String transactionId ) {
        super();
        this.amount = amount;
        this.transactionId = transactionId ;
    }

    public Transaction() {
        super();
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public String getTransactionId() {
        return transactionId;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public void setTransactionId(String transactionId) {
        this.transactionId = transactionId;
    }
}

When serializing the Response class, I get this XML.

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <approved>00</approved>
   <errorCode></errorCode>
   <transaction>
      <amount>500.00</amount>
      <transactionId>pgka3902</transactionId>
   </transaction>
   <transaction>
      <amount>201.05</amount>
      <transactionId>abcd3020</transactionId>
   </transaction>
</response>

Adding @XmlElementWrapper wraps <transaction> elements in <collection> which is not acceptable still. I need the wrapper to be named the plural of the actual type in collection. For example, the above xml should be:

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <approved>00</approved>
   <errorCode />
   <transactions>
      <transaction>
         <amount>500.00</amount>
         <transactionId>pgka3902</transactionId>
      </transaction>
      <transaction>
         <amount>201.05</amount>
         <transactionId>abcd3020</transactionId>
      </transaction>
   </transactions>
</response>

Is it possible to do this with JAXB? I'm using Eclipselink Moxy implementation.

isah
  • 5,221
  • 3
  • 26
  • 36

2 Answers2

2

Instead of Response holding a Collection you could change that to Object. Then you could have different classes for each of your collection types.

 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 public class Transactions {

     @XmlElement(name="transaction")
     private List<Transaction> transactions;

 }
bdoughan
  • 147,609
  • 23
  • 300
  • 400
0

The @XmlElementWrapper annotation has an optional parameter: name. If not specified, by default it will be the name of the Java field which is collection in your case. That's why your wrapper tag is named <collection>.

You can specify the name of the wrapper element/tag by passing the name argument to the @XmlElementWrapper annotation like this:

@XmlElementWrapper(name="transactions")

This will result in your desired XML tags.

icza
  • 389,944
  • 63
  • 907
  • 827
  • Thanks, but you missed my point. This should be dynamic, depending on actual type in Collection>. – isah Nov 10 '14 at 13:07
  • @isah I don't think that's possible. If it would be, JAXB would not be able to unmarshal an XML generated like this. Also a collection might contain elements of different types, how would you name the element then? – icza Nov 10 '14 at 13:09
  • Actually it looks possible to me. I can use generics or bounded wildards which can contain specific types. Something similar is done here: http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html – isah Nov 10 '14 at 13:13
  • @isah Yes, but about unmarshaling, I was referring to this: what if your class has a field named `transactions`, it will end up in ``. And now if your `collection` field contains `Transaction`s, by this rule it will also end up using the element ``. Now JAXB will have trouble unmarsaling this. – icza Nov 10 '14 at 13:44