I presume there was a copy error in your XML. Either your root element is <partlist>
or it is missing the elements Part_Number, Part_Version, Part_Type and Status (that would make sense). So your schema would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.serus.com" xmlns:ns1="http://www.serus.com">
<xs:element name="part">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element ref="ns1:Part_Number"/>
<xs:element ref="ns1:Part_Type"/>
<xs:element ref="ns1:Part_Version"/>
<xs:element ref="ns1:Status"/>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="ns1:part"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Part_Number" type="xs:NCName"/>
<xs:element name="Part_Type" type="xs:NCName"/>
<xs:element name="Part_Version" type="xs:NCName"/>
<xs:element name="Status" type="xs:NCName"/>
</xs:schema>
Then a class would have this format:
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement(name = "part")
public class Part implements Serializable {
public static Part fromXML(InputStream in) throws Exception {
JAXBContext context = JAXBContext.newInstance(Part.class);
Unmarshaller um = context.createUnmarshaller();
return (Part) um.unmarshal(in);
}
private static final long serialVersionUID = 1L;
@XmlElement(name = "Part_Number")
private String partNumber;
@XmlElement(name = "Part_Type")
private String partType;
@XmlElement(name = "Part_Version")
private String partVersion;
@XmlElement(name = "Status")
private String status;
@XmlElement(name = "part")
private Collection<Part> subParts = null;
public static void main(String args[]) throws JAXBException {
Part mainPart = new Part("1m", "mType", "version 1", "draft");
Part level1 = new Part("l1", "l1Type", "version 11", "new");
level1.addPart(new Part("l2", "l2Type", "version 1", "new"));
level1.addPart(new Part("l2-2", "l2Type", "version 1", "new"));
mainPart.addPart(level1);
System.out.println(mainPart.toXML());
}
public Part() {
// No action here
}
public Part(String no, String type, String ver, String stat) {
this.partNumber = no;
this.partType = type;
this.partVersion = ver;
this.status = stat;
}
@XmlTransient
public String getPartNumber() {
return this.partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
@XmlTransient
public String getPartType() {
return this.partType;
}
public void setPartType(String partType) {
this.partType = partType;
}
@XmlTransient
public String getPartVersion() {
return this.partVersion;
}
public void setPartVersion(String partVersion) {
this.partVersion = partVersion;
}
@XmlTransient
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
@XmlTransient
public Collection<Part> getSubparts() {
return this.subParts;
}
public void setSubparts(Collection<Part> subparts) {
this.subParts = subparts;
}
public void addPart(Part part) {
if (this.subParts == null) {
this.subParts = new ArrayList<Part>();
}
this.subParts.add(part);
}
public void addParts(Collection<Part> parts) {
if (this.subParts == null) {
this.subParts = new ArrayList<Part>();
}
this.subParts.addAll(parts);
}
public String toXML() throws JAXBException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
JAXBContext context = JAXBContext.newInstance(Part.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(this, out);
return out.toString();
}
}
The trick here is the strategic use of @XmlElement(name = "part")
and @XmlTransient
. That should do the trick