Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB unmarshalling: child elements are null

I am trying to unmarshal a XML document:

<map>
   <room id="1" name="Stairway" east="2"/>
   <room id="2" name="Kitchen" north="4" south="3" west="1">
       <object name="Hat"/>
   </room>
   <room id="3" name="Hallway" east="1" south="4">
       <object name="Money"/>
   </room>
   <room id="4" name="Bathroom" south="2"/>
</map>

And the XSD schema (generated by some tool):

<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="map">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element minOccurs="1" maxOccurs="unbounded" name="room">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element minOccurs="0" maxOccurs="unbounded" name="object">
                <xsd:complexType>
                  <xsd:attribute name="name" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
            <xsd:attribute name="id" type="xsd:int" />
            <xsd:attribute name="name" type="xsd:string" />
            <xsd:attribute name="north" type="xsd:int" />
            <xsd:attribute name="south" type="xsd:int" />
            <xsd:attribute name="west" type="xsd:int" />
            <xsd:attribute name="east" type="xsd:int" />
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

These are the important model classes:

Map.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"rooms"})
@XmlRootElement(name = "map")
public class Map {

    /**
     * List of rooms contained in this map.
     */
    @XmlElement(required = true)
    protected List<Room> rooms;

    /**
     * Gets the value of the rooms property.
     *
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB objects.
     * This is why there is not a <CODE>set</CODE> method for the rooms property.
     *
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getRooms().add(newItem);
     * </pre>
     *
     *
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Room }
     *
     *
     */
    public List<Room> getRooms() {
        if (rooms == null) {
            rooms = new ArrayList<Room>();
        }
        return this.rooms;
    }

}

Room.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
        "objects"
})
public class Room {

    @XmlElement(required = true)
    protected List<Object> objects;
    @XmlAttribute(name = "id")
    protected Integer id;
    @XmlAttribute(name = "name")
    protected String name;
    @XmlAttribute(name = "north")
    protected Integer north;
    @XmlAttribute(name = "south")
    protected Integer south;
    @XmlAttribute(name = "west")
    protected Integer west;
    @XmlAttribute(name = "east")
    protected Integer east;

    /**
     * Gets the value of the objects property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB objects.
     * This is why there is not a <CODE>set</CODE> method for the objects property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getObjects().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link Object }
     * 
     * 
     */
    public List<Object> getObjects() {
        if (objects == null) {
            objects = new ArrayList<Object>();
        }
        return this.objects;
    }

    /**
     * Ruft den Wert der id-Eigenschaft ab.
     * 
     * @return
     *     possible objects is
     *     {@link Integer }
     *     
     */
    public Integer getId() {
        return id;
    }

    /**
     * Legt den Wert der id-Eigenschaft fest.
     * 
     * @param value
     *     allowed objects is
     *     {@link Integer }
     *     
     */
    public void setId(Integer value) {
        this.id = value;
    }

    /**
     * Ruft den Wert der name-Eigenschaft ab.
     * 
     * @return
     *     possible objects is
     *     {@link String }
     *     
     */
    public String getName() {
        return name;
    }

    /**
     * Legt den Wert der name-Eigenschaft fest.
     * 
     * @param value
     *     allowed objects is
     *     {@link String }
     *     
     */
    public void setName(String value) {
        this.name = value;
    }

    /**
     * Ruft den Wert der north-Eigenschaft ab.
     * 
     * @return
     *     possible objects is
     *     {@link Integer }
     *     
     */
    public Integer getNorth() {
        return north;
    }

    /**
     * Legt den Wert der north-Eigenschaft fest.
     * 
     * @param value
     *     allowed objects is
     *     {@link Integer }
     *     
     */
    public void setNorth(Integer value) {
        this.north = value;
    }

    /**
     * Ruft den Wert der south-Eigenschaft ab.
     * 
     * @return
     *     possible objects is
     *     {@link Integer }
     *     
     */
    public Integer getSouth() {
        return south;
    }

    /**
     * Legt den Wert der south-Eigenschaft fest.
     * 
     * @param value
     *     allowed objects is
     *     {@link Integer }
     *     
     */
    public void setSouth(Integer value) {
        this.south = value;
    }

    /**
     * Ruft den Wert der west-Eigenschaft ab.
     * 
     * @return
     *     possible objects is
     *     {@link Integer }
     *     
     */
    public Integer getWest() {
        return west;
    }

    /**
     * Legt den Wert der west-Eigenschaft fest.
     * 
     * @param value
     *     allowed objects is
     *     {@link Integer }
     *     
     */
    public void setWest(Integer value) {
        this.west = value;
    }

    /**
     * Ruft den Wert der east-Eigenschaft ab.
     * 
     * @return
     *     possible objects is
     *     {@link Integer }
     *     
     */
    public Integer getEast() {
        return east;
    }

    /**
     * Legt den Wert der east-Eigenschaft fest.
     * 
     * @param value
     *     allowed objects is
     *     {@link Integer }
     *     
     */
    public void setEast(Integer value) {
        this.east = value;
    }

}

Now when I try to unmarshall that XML map.rooms is always null, there should be the list of rooms.

Any idea what causes this and how to fix it?

like image 548
lenny Avatar asked Oct 27 '25 03:10

lenny


1 Answers

I think you should either provide the name in XmlElement

@XmlElement(name = "room", required = true)
protected List<Room> rooms;

Either, change the name of your list into room instead of rooms

@XmlElement(required = true)
protected List<Room> room;
like image 180
Mickael Avatar answered Oct 28 '25 17:10

Mickael