How to wrap sublist with jaxb

13,729

Solution 1

Instead of

/**
 * getter for orders
 * @return orders
 */
@XmlElement(name="orders", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };

You need

/**
 * getter for orders
 * @return orders
 */
@XmlElement(name="order", type=OrderJaxbDao.class)
@XmlElementWrapper(name="orders")
public List<Order> getOrders() { return orders; };

The @XmlElementWrapper name is the name of the wrapping element (orders) and the @XmlElement name is the name of the per-entry element inside the wrapper (order).

Solution 2

This seems to do the trick:

  @XmlElementWrapper(name="orders")
  @XmlElement(name="order", type=OrderJaxbDao.class)
  public List<Order> getOrders() { return orders; };

improved CustomerJaxbDao

/**
 * Copyright (C) 2011-2012 BITPlan GmbH
 * 
 * http://www.bitplan.com
 * 
 * generated: 2012-10-16 12:20 with smartGENERATOR
 */
package com.bitplan.testentity.jaxb;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlElement;
import com.bitplan.testentity.Customer;

import java.util.List;
import com.bitplan.testentity.Order;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.ArrayList;

/**
 * JaxB Data access object for Customer
 * Entity: Customer for container testentity
 * Table: Customer
 */
@XmlRootElement(name="Customer")
public class CustomerJaxbDao implements Customer {
  /**
   * name
   */
  private String name;

  /**
   * id
   */
  private long id;

  /**
   * orders
   */
  private List<Order> orders=new ArrayList<Order>();

  /**
   * getter for name
   * @return name
   */
  @XmlElement(name="name")  
  public String getName() { return name; };

  /**
   * setter for name
   * @param pname - new value for name
   */
  public void setName(String pname) { name=pname; };

  /**
   * getter for id
   * @return id
   */
  @XmlElement(name="id")  
  public long getId() { return id; };

  /**
   * setter for id
   * @param pid - new value for id
   */
  public void setId(long pid) { id=pid; };

  /**
   * getter for orders
   * @return orders
   */
  @XmlElementWrapper(name="orders")
  @XmlElement(name="order", type=OrderJaxbDao.class)
  public List<Order> getOrders() { return orders; };

  /**
   * setter for orders
   * @param porders - new value for orders
   */
  public void setOrders(List<Order> porders) { orders=porders; };


} // CustomerJaxbDao

Solution 3

It sounds like you want to wrap the Order in your CustomerJaxbDao class.

@XmlElementWrapper( name="orders" )
@XmlElement(name="order", type=OrderJaxbDao.class)
public List<Order> getOrders() { return orders; };

Might do what you want.

Share:
13,729

Related videos on Youtube

Wolfgang Fahl
Author by

Wolfgang Fahl

Teacher for software architects CEO of BITPlan GmbH http://www.bitplan.com Founding Member and Initiator of iSAQB e.V. http://www.isaqb.org

Updated on October 03, 2022

Comments

  • Wolfgang Fahl
    Wolfgang Fahl about 1 year

    When trying to map a customer-> order 1:n relationship with jaxb 2.2.6 I'd like to get the list of orders wrapped in a separate node "orders".

    currently the result is:

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
        <Customer>
           <id>100</id>
           <name>John Doe</name>
           <orders>
             <address>100 main street, smalltown, pa</address>
             <orderid>1100</orderid>
           </orders>
          <orders>
             <address>5 broadway, ny, ny</address>
             <orderid>1200</orderid>
           </orders> 
        </Customer>
    

    but I'd like to get:

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
        <Customer>
           <id>100</id>
           <name>John Doe</name>
           <orders>
             <order>
               <address>100 main street, smalltown, pa</address>
               <orderid>1100</orderid>
             </order>
             <order>
                <address>5 broadway, ny, ny</address>
                <orderid>1200</orderid>
             </order>
           </orders> 
        </Customer>
    

    What needs to be changed to get this result?

    The relevant source code has:

    • Customer interface
    • CustomerJaxbDao implementation
    • Order interface
    • OrderJaxbDao implementation
    • TestCustomerWrite Junit4 Testcase

    and uses this jaxb implementation:

                <!-- JAXB -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.2.6</version>
        </dependency>
    

    Customer interface:

    /**
     * Copyright (C) 2011-2012 BITPlan GmbH
     * 
     * http://www.bitplan.com
     *
     * generated: 2012-10-15 15:12 with smartGENERATOR
     */
    package com.bitplan.testentity;
    import java.util.List;
    import com.bitplan.testentity.Order;
    
    
    /**
     * interface for Customer
     */
    public interface Customer {
        // >>>{interface}{Customer}{Customer}
        // no implementation yet !!!
        // <<<{interface}{Customer}{Customer}
      /**
       * getter for name
       * @return name
       */
      public String getName();
    
      /**
       * setter for name
       * @param pname - new value for name
       */
      public void setName(String pname);
    
      /**
       * getter for id
       * @return id
       */
      public long getId();
    
      /**
       * setter for id
       * @param pid - new value for id
       */
      public void setId(long pid);
    
      /**
       * getter for orders
       * @return orders
       */
      public List<Order> getOrders();
    
      /**
       * setter for orders
       * @param porders - new value for orders
       */
      public void setOrders(List<Order> porders);
    
    } // Customer
    

    Order interface:

    /**
     * Copyright (C) 2011-2012 BITPlan GmbH
     * 
     * http://www.bitplan.com
     *
     * generated: 2012-10-15 at 23:59 with smartGENERATOR
     */
    package com.bitplan.testentity;
    
    /**
     * interface for Order
     */
    public interface Order {
        // >>>{interface}{Order}{Order}
        // no implementation yet !!!
        // <<<{interface}{Order}{Order}
      /**
       * getter for orderid
       * @return orderid
       */
      public long getOrderid();
    
      /**
       * setter for orderid
       * @param porderid - new value for orderid
       */
      public void setOrderid(long porderid);
    
      /**
       * getter for shipping address
       * @return address
       */
      public String getAddress();
    
      /**
       * setter for shipping address
       * @param paddress - new value for shipping address
       */
      public void setAddress(String paddress);
    
    } // Order
    

    CustomerJaxbDao implementation

    /**
     * Copyright (C) 2011-2012 BITPlan GmbH
     * 
     * http://www.bitplan.com
     *
     * generated: 2012-10-15 at 23:51 with smartGENERATOR
     */
    package com.bitplan.testentity.jaxb;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlElement;
    
    import com.bitplan.testentity.Order;
    import com.bitplan.testentity.Customer;
    
    import java.util.List;
    import java.util.ArrayList;
    
    /**
     * JaxB Data access object for Customer
     * Entity: Customer for container testentity
     * Table: Customer
     */
    @XmlRootElement(name="Customer")
    public class CustomerJaxbDao implements Customer {
      /**
       * name
       */
      private String name;
    
      /**
       * id
       */
      private long id;
    
      /**
       * orders
       */
      private List<Order> orders=new ArrayList<Order>();
    
      /**
       * getter for name
       * @return name
       */
      @XmlElement(name="name")
      public String getName() { return name; };
    
      /**
       * setter for name
       * @param pname - new value for name
       */
      public void setName(String pname) { name=pname; };
    
      /**
       * getter for id
       * @return id
       */
      @XmlElement(name="id")
      public long getId() { return id; };
    
      /**
       * setter for id
       * @param pid - new value for id
       */
      public void setId(long pid) { id=pid; };
    
      /**
       * getter for orders
       * @return orders
       */
      @XmlElement(name="orders", type=OrderJaxbDao.class)
      public List<Order> getOrders() { return orders; };
    
      /**
       * setter for orders
       * @param porders - new value for orders
       */
      public void setOrders(List<Order> porders) { orders=porders; };
    
    
    } // CustomerJaxbDao
    

    OrderJaxbDao implementation

    /**
     * Copyright (C) 2011-2012 BITPlan GmbH
     * 
     * http://www.bitplan.com
     *
     * generated: 2012-10-15 with smartGENERATOR
     */
    package com.bitplan.testentity.jaxb;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlElement;
    import com.bitplan.testentity.Order;
    
    
    /**
     * JaxB Data access object for Order
     * Entity: Order for container testentity
     * Table: Order
     */
    @XmlRootElement(name="Order")
    public class OrderJaxbDao implements Order {
      /**
       * orderid
       */
      private long orderid;
    
      /**
       * shipping address
       */
      private String address;
    
      /**
       * getter for orderid
       * @return orderid
       */
      @XmlElement(name="orderid")
      public long getOrderid() { return orderid; };
    
      /**
       * setter for orderid
       * @param porderid - new value for orderid
       */
      public void setOrderid(long porderid) { orderid=porderid; };
    
      /**
       * getter for shipping address
       * @return address
       */
      @XmlElement(name="address")
      public String getAddress() { return address; };
    
      /**
       * setter for shipping address
       * @param paddress - new value for shipping address
       */
      public void setAddress(String paddress) { address=paddress; };
    
    
    } // OrderJaxbDao
    

    TestCustomerWrite Junit4 Testcase

    package com.bitplan.storage.jaxb;
    
    import static org.junit.Assert.*;
    
    import java.io.StringWriter;
    
    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    
    import org.junit.Test;
    
    import com.bitplan.testentity.Customer;
    import com.bitplan.testentity.Order;
    import com.bitplan.testentity.jaxb.CustomerJaxbDao;
    import com.bitplan.testentity.jaxb.OrderJaxbDao;
    
    /**
     * 
     * @author wf
     *
     */
    public class TestCustomerWrite {
    
        @Test
        public void test() throws JAXBException {
            Customer customer=new CustomerJaxbDao();
            customer.setId(100);
            customer.setName("John Doe");
            long orderid=1000;
            String[] addresses={"100 main street, smalltown, pa","5 broadway, ny, ny"};
            for (String address:addresses) {
                Order order=new OrderJaxbDao();
                order.setAddress(address);
                order.setOrderid(orderid+=100);
                customer.getOrders().add(order);
            }
            JAXBContext jaxbContext = JAXBContext.newInstance(CustomerJaxbDao.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    
            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    
            StringWriter sw=new StringWriter();
            jaxbMarshaller.marshal(customer, sw);
            System.out.println(sw);
    
        }
    
    }