Restricting XML attribute to enum values - java

Here is the XSD schema that i created for a WS
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="shipmentStatus" type="shipmentStatusType" />
<xs:complexType name="shipmentStatusType">
<xs:sequence>
<xs:element name="orderNumber" type="xs:int"/>
</xs:sequence>
<xs:attribute name="requestStatus">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="SHIPPED"/>
<xs:enumeration value="PENDING"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
When i generated Java classes using JAXB 2.1, it generated only one class i.e. shipmentStatusType. I was expecting that it will generate requestStatus as a JAVA Enum but it didn't. Is it an expected behaviour or did i miss something?

Just extract your enum/simple type declaration to top-level one and use it as type of the XML attribute:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com" xmlns="http://www.example.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:simpleType name="requestStatus">
<xs:restriction base="xs:string">
<xs:enumeration value="SHIPPED" />
<xs:enumeration value="PENDING" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shipmentStatus">
<xs:sequence>
<xs:element name="orderNumber" type="xs:int" />
</xs:sequence>
<xs:attribute name="requestStatus" type="requestStatus" />
</xs:complexType>
<xs:element name="shipmentStatus" type="shipmentStatus" />
</xs:schema>
It will give you such an enum:
/**
* <p>Java class for requestStatus.
*
* <p>The following schema fragment specifies the expected content contained within this class.
* <p>
* <pre>
* <simpleType name="requestStatus">
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
* <enumeration value="SHIPPED"/>
* <enumeration value="PENDING"/>
* </restriction>
* </simpleType>
* </pre>
*
*/
#XmlType(name = "requestStatus")
#XmlEnum
public enum RequestStatus {
SHIPPED,
PENDING;
public String value() {
return name();
}
public static RequestStatus fromValue(String v) {
return valueOf(v);
}
}
and class having it:
/**
* <p>Java class for shipmentStatus complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="shipmentStatus">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="orderNumber" type="{http://www.w3.org/2001/XMLSchema}int"/>
* </sequence>
* <attribute name="requestStatus" type="{http://www.example.com}requestStatus" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "shipmentStatus", propOrder = {
"orderNumber"
})
public class ShipmentStatus {
protected int orderNumber;
#XmlAttribute(name = "requestStatus")
protected RequestStatus requestStatus;
/**
* Gets the value of the orderNumber property.
*
*/
public int getOrderNumber() {
return orderNumber;
}
/**
* Sets the value of the orderNumber property.
*
*/
public void setOrderNumber(int value) {
this.orderNumber = value;
}
/**
* Gets the value of the requestStatus property.
*
* #return
* possible object is
* {#link RequestStatus }
*
*/
public RequestStatus getRequestStatus() {
return requestStatus;
}
/**
* Sets the value of the requestStatus property.
*
* #param value
* allowed object is
* {#link RequestStatus }
*
*/
public void setRequestStatus(RequestStatus value) {
this.requestStatus = value;
}
}

I think that you're asking the same thing as this SO post. You need to create a custom binding file to map this simple type to an enumeration.
The binding file:
<jaxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc" version="2.1">
<jaxb:globalBindings generateIsSetMethod="true" fixedAttributeAsConstantProperty="true">
<xjc:serializable/>
</jaxb:globalBindings>
<jaxb:bindings schemaLocation="file:/..../restricting-xml-attribute-to-enum-values.xsd">
<jaxb:bindings node="//xs:complexType[#name='shipmentStatusType']/xs:attribute[#name='requestStatus']/xs:simpleType">
<jaxb:typesafeEnumClass name="MyEnumType"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
The generated class (the relevant part):
/**
* <p>Java class for null.
*
* <p>The following schema fragment specifies the expected content contained within this class.
* <p>
* <pre>
* <simpleType>
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
* <enumeration value="SHIPPED"/>
* <enumeration value="PENDING"/>
* </restriction>
* </simpleType>
* </pre>
*
*/
#XmlType(name = "")
#XmlEnum
public enum MyEnumType {
SHIPPED,
PENDING;
public String value() {
return name();
}
public static ShipmentStatusType.MyEnumType fromValue(String v) {
return valueOf(v);
}
}

Related

How to generate XML properly with JAXB in JAVA

maybe my question are similiar like these question How do I parse this XML in Java with JAXB?
i want to generate some XML files to display some data
but i have different problem with using some #XmlAttribute & #XmlValue properly in JAXBthis is XML output supposed to be:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AnlKerja>
<Analisa no="1">
<Kode>B.1</Kode>
<Uraian>some description</Uraian>
<Material>
<item type="value">ID|ID|ID</item>
</Material>
<Jumlah>some value</Jumlah>
</Analisa>
<Analisa no="2">
<Kode>B.3</Kode>
<Uraian>some description</Uraian>
<Material>
<item type="value">ID|ID|ID</item>
<item type="value">ID|ID|ID</item>
</Material>
<Jumlah>some value</Jumlah>
</Analisa>
</AnlKerja>
since i'm using JAXB 2 days ago
i dont know how to use it properly,
and its kinda hard for me to read the JAXB documentation guide
because my native language isn't English.
this is my java code for JAXB
AnlKerja.java
#XmlRootElement(name = "AnlKerja")
public class AnlKerja {
#XmlElementWrapper(name = "Analisa")
#XmlElement(name = "Analisa")
private ArrayList<Analisa> analisa;
public ArrayList<Analisa> getAnl() {
return analisa;
}
public void setAnl(ArrayList<Analisa> anl) {
this.analisa = anl;
}
}
Analisa.java
#XmlRootElement(name="Analisa")
#XmlType(propOrder = {"no","value","kode","uraian","material","jumlah"})
public class Analisa {
#XmlAttribute
private String no;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
#XmlValue
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
private String kode,uraian;
private double jumlah;
#XmlElement(name="Kode")
public String getKode() {
return kode;
}
public void setKode(String kode) {
this.kode = kode;
}
#XmlElement(name="Uraian")
public String getUraian() {
return uraian;
}
public void setUraian(String uraian) {
this.uraian = uraian;
}
#XmlElementWrapper(name = "material")
private ArrayList<Material> material;
public ArrayList<Material> getMaterial() {
return material;
}
public void setMaterial(ArrayList<Material> material) {
this.material = material;
}
#XmlElement(name="Jumlah")
public double getJumlah() {
return jumlah;
}
public void setJumlah(double jumlah) {
this.jumlah = jumlah;
}
}
Material.java
#XmlRootElement(name = "Material")
public class Material {
#XmlElement(name = "items")
private String items;
public Material() {
this.items = "";
this.tipe = "";
this.value = "";
}
public Material(String[] isi, String tipe, String deskripsi) {
int temp = isi.length;
for (int x=0; x<temp; x++) {
this.items += isi[x]+"|";
};
this.value = deskripsi;
this.tipe = tipe;
}
public String getItems() {
return items;
}
public void setItems(String items) {
this.items = items;
}
public void setItems(String[] items) {
int temp = items.length;
for (int x=0; x<temp; x++) {
this.items += items[x]+"|";
}
}
#XmlAttribute
private String tipe;
public String getTipe() {
return tipe;
}
public void setTipe(String tipe) {
this.tipe = tipe;
}
#XmlValue
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Demo.java
public class Demo {
private static final String STORE_XML = "results/ANL.xml";
public static void main(String[] args) throws JAXBException, IOException{
ArrayList<Material> mtr = new ArrayList<Material>();
ArrayList<Analisa> anl = new ArrayList<Analisa>();
AnlKerja anKerja = new AnlKerja();
Material mat = new Material();
mat.setTipe("tipe");
mat.setValue("Bahan");
mat.setItems("MT001|MT002|MT003");
mtr.add(mat);
mat.setTipe("tipe");
mat.setValue("Tenaga");
mat.setItems("MT0001|MT0002|MT0003");
mtr.add(mat);
Analisa ana = new Analisa();
ana.setNo("no");
ana.setValue(1);
ana.setKode("B.1");
ana.setUraian("some description");
ana.setMaterial(mtr);
ana.setJumlah(122414.03);
anl.add(ana);
anKerja.setAnl(anl);
JAXBContext jCont = JAXBContext.newInstance(AnlKerja.class);
Marshaller marshal = jCont.createMarshaller();
marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshal.marshal(anKerja, System.out);
marshal.marshal(anKerja, new File(STORE_XML));
}
}
this is the error i get
Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 8 counts of IllegalAnnotationExceptions
If a class has #XmlElement property, it cannot have #XmlValue property.
this problem is related to the following location:
at private int XML.Analisa.value
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at public int XML.Analisa.getValue()
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
If a class has #XmlElement property, it cannot have #XmlValue property.
this problem is related to the following location:
at private java.lang.String XML.Material.value
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at public java.lang.String XML.Material.getValue()
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
Class has two properties of the same name "material"
this problem is related to the following location:
at public java.util.ArrayList XML.Analisa.getMaterial()
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
Class has two properties of the same name "no"
this problem is related to the following location:
at public java.lang.String XML.Analisa.getNo()
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at private java.lang.String XML.Analisa.no
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
Class has two properties of the same name "value"
this problem is related to the following location:
at public int XML.Analisa.getValue()
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at private int XML.Analisa.value
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
Class has two properties of the same name "items"
this problem is related to the following location:
at public java.lang.String XML.Material.getItems()
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at private java.lang.String XML.Material.items
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
Class has two properties of the same name "tipe"
this problem is related to the following location:
at public java.lang.String XML.Material.getTipe()
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at private java.lang.String XML.Material.tipe
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
Class has two properties of the same name "value"
this problem is related to the following location:
at public java.lang.String XML.Material.getValue()
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
this problem is related to the following location:
at private java.lang.String XML.Material.value
at XML.Material
at private java.util.ArrayList XML.Analisa.material
at XML.Analisa
at private java.util.ArrayList XML.AnlKerja.analisa
at XML.AnlKerja
This is XML, not XML schema
you have some errors in your XML file: tag item is not closed on some lines.
After fixing this you can create XSD from XML on one of online services, for example: https://www.freeformatter.com/xsd-generator.html
With your XSD file you can create JAXB binding classes with xjc utility (https://docs.oracle.com/javase/8/docs/technotes/tools/unix/xjc.html) from JDK
upd the generated class:
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2019.05.05 at 08:59:07 PM MSK
//
package generated;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Analisa" maxOccurs="unbounded" minOccurs="0">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Kode" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="Uraian" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="Material">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="item" maxOccurs="unbounded" minOccurs="0">
* <complexType>
* <simpleContent>
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* <element name="Jumlah" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* <attribute name="no" type="{http://www.w3.org/2001/XMLSchema}byte" />
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"analisa"
})
#XmlRootElement(name = "AnlKerja")
public class AnlKerja {
#XmlElement(name = "Analisa")
protected List<AnlKerja.Analisa> analisa;
/**
* Gets the value of the analisa 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 object.
* This is why there is not a <CODE>set</CODE> method for the analisa property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getAnalisa().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link AnlKerja.Analisa }
*
*
*/
public List<AnlKerja.Analisa> getAnalisa() {
if (analisa == null) {
analisa = new ArrayList<AnlKerja.Analisa>();
}
return this.analisa;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Kode" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="Uraian" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="Material">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="item" maxOccurs="unbounded" minOccurs="0">
* <complexType>
* <simpleContent>
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* <element name="Jumlah" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* <attribute name="no" type="{http://www.w3.org/2001/XMLSchema}byte" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"kode",
"uraian",
"material",
"jumlah"
})
public static class Analisa {
#XmlElement(name = "Kode", required = true)
protected String kode;
#XmlElement(name = "Uraian", required = true)
protected String uraian;
#XmlElement(name = "Material", required = true)
protected AnlKerja.Analisa.Material material;
#XmlElement(name = "Jumlah", required = true)
protected String jumlah;
#XmlAttribute(name = "no")
protected Byte no;
/**
* Gets the value of the kode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getKode() {
return kode;
}
/**
* Sets the value of the kode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setKode(String value) {
this.kode = value;
}
/**
* Gets the value of the uraian property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getUraian() {
return uraian;
}
/**
* Sets the value of the uraian property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setUraian(String value) {
this.uraian = value;
}
/**
* Gets the value of the material property.
*
* #return
* possible object is
* {#link AnlKerja.Analisa.Material }
*
*/
public AnlKerja.Analisa.Material getMaterial() {
return material;
}
/**
* Sets the value of the material property.
*
* #param value
* allowed object is
* {#link AnlKerja.Analisa.Material }
*
*/
public void setMaterial(AnlKerja.Analisa.Material value) {
this.material = value;
}
/**
* Gets the value of the jumlah property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getJumlah() {
return jumlah;
}
/**
* Sets the value of the jumlah property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setJumlah(String value) {
this.jumlah = value;
}
/**
* Gets the value of the no property.
*
* #return
* possible object is
* {#link Byte }
*
*/
public Byte getNo() {
return no;
}
/**
* Sets the value of the no property.
*
* #param value
* allowed object is
* {#link Byte }
*
*/
public void setNo(Byte value) {
this.no = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="item" maxOccurs="unbounded" minOccurs="0">
* <complexType>
* <simpleContent>
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"item"
})
public static class Material {
protected List<AnlKerja.Analisa.Material.Item> item;
/**
* Gets the value of the item 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 object.
* This is why there is not a <CODE>set</CODE> method for the item property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getItem().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link AnlKerja.Analisa.Material.Item }
*
*
*/
public List<AnlKerja.Analisa.Material.Item> getItem() {
if (item == null) {
item = new ArrayList<AnlKerja.Analisa.Material.Item>();
}
return this.item;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <simpleContent>
* <extension base="<http://www.w3.org/2001/XMLSchema>string">
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
* </extension>
* </simpleContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"value"
})
public static class Item {
#XmlValue
protected String value;
#XmlAttribute(name = "type")
protected String type;
/**
* Gets the value of the value property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getValue() {
return value;
}
/**
* Sets the value of the value property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setValue(String value) {
this.value = value;
}
/**
* Gets the value of the type property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getType() {
return type;
}
/**
* Sets the value of the type property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setType(String value) {
this.type = value;
}
}
}
}
}
i found some solution but it still didnt solve the real problem that i facing now.
i found this tutorial HERE
and i change little bit of my codeAnlKerja.java
#XmlRootElement
public class AnlKerja {
private ArrayList<Analisa> analisa;
// removed #XmlElementWrapper & #XmlElement
public ArrayList<Analisa> getAnalisa() {
return analisa;
}
public void setAnalisa(ArrayList<Analisa> anl) {
this.analisa = anl;
}
}
Analisa.java
placing variable in the right order & remove #XmlElement
private String kode,uraian;
private ArrayList<Material> material;
private double jumlah;
private String no;
removed #XmlValue
and re-arrange #XmlAttribute to bottom line code
#XmlAttribute
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
Material.java i did same to material, remove #XmlValue and its variable
#XmlAttribute
public String getTipe() {
return tipe;
}
public void setTipe(String tipe) {
this.tipe = tipe;
}
and the rest i remove ana.setValue(1); from Demo.java
and this are the result i get for my XML files.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<anlKerja>
<analisa no="1">
<kode>B.1</kode>
<uraian>Some Description</uraian>
<material tipe="Tenaga">
<items>MT001|MT002|MT003</items>
</material>
<material tipe="Bahan">
<items>MT0001|MT0002|MT0003</items>
</material>
<jumlah>122414.03</jumlah>
</analisa>
</anlKerja>
its almost look like what i wanted but still there is some child element that i wanted to change
<material tipe="Bahan">
<items>MT0001|MT0002|MT0003</items>
</material>
to this
<Material>
<item type="Bahan">ID|ID|ID</item>
</Material>
Or this
<Material>
<item type="Bahan">ID|ID|ID</item>
<item type="Tenaga">ID|ID|ID</item>
</Material>
should i create additional class for item?
or tweak some code in Material.java ?

How to different objects into the same list using #XmlElements?

I want to use jackson xml mapper to map the following xml (that I have to control of and get from a webservice) to a java bean:
<foo>
<first><val>some</val></first>
<first><val>somemore</val></first>
<second><testval>test</testval></second>
</foo>
The schema I'm supplied with is:
<xs:schema>
<xs:include schemaLocation="firstType.xsd"/>
<xs:include schemaLocation="secondType.xsd"/>
<xs:element name="foo">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element ref="first" minOccurs="0"/>
<xs:element ref="second" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Using xsdtojava, this generates the following bean:
#XmlRootElement(name = "foo")
#XmlAccessorType(XmlAccessType.FIELD)
public class XmlTest {
#XmlElements({
#XmlElement(name = "first", type = FirstType.class),
#XmlElement(name = "second", type = SecondType.class)
})
#JsonSubTypes({
#JsonSubTypes.Type(name = "first", value = FirstType.class),
#JsonSubTypes.Type(name = "second" , value = SecondType.class)
})
private List<IType> items;
//grouping interface
interface IType {
}
#XmlRootElement(name = "first")
#XmlAccessorType(XmlAccessType.FIELD)
class FirstType implements IType {
private String val;
}
#XmlRootElement(name = "second")
#XmlAccessorType(XmlAccessType.FIELD)
class SecondType implements IType {
private String testval;
}
}
But my test fails to convert the xml!
public static void main(String[] args) throws Exception {
String xml =
"<foo>" +
"<first><val>some</val></first>" +
"<second><testval>test</testval></second>" +
"</foo>";
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
ObjectMapper mapper = builder
.modules(new JaxbAnnotationModule(), new JacksonXmlModule())
.defaultUseWrapper(false)
.createXmlMapper(true)
.build();
XmlTest unmarshal = mapper.readValue(xml, XmlTest.class);
System.out.println(unmarshal.items); //prints 'null'
}
The result list of items always null, but why?
I tried both #XmlElements and #JsonSubTypes, but none worked.
I've done a new test :
The XSD : (like yours)
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/test" xmlns:tns="http://www.example.org/test" elementFormDefault="qualified">
<element name="foo">
<complexType>
<sequence maxOccurs="unbounded">
<element name="first" type="tns:FirstType"
maxOccurs="unbounded" minOccurs="0">
</element>
<element name="second" type="tns:SecondType"
maxOccurs="unbounded" minOccurs="0">
</element>
</sequence>
</complexType>
</element>
<complexType name="FirstType">
<sequence>
<element name="val" type="string"></element>
</sequence>
</complexType>
<complexType name="SecondType">
<sequence>
<element name="testval" type="string"></element>
</sequence>
</complexType>
</schema>
The JAVA generated by xjc plugin :
Foo.class :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"firstAndSecond"
})
#XmlRootElement(name = "foo")
public class Foo {
#XmlElements({
#XmlElement(name = "second", type = SecondType.class),
#XmlElement(name = "first", type = FirstType.class)
})
protected List<Object> firstAndSecond;
/**
* Gets the value of the firstAndSecond 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 object.
* This is why there is not a <CODE>set</CODE> method for the firstAndSecond property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getFirstAndSecond().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link SecondType }
* {#link FirstType }
*
*
*/
public List<Object> getFirstAndSecond() {
if (firstAndSecond == null) {
firstAndSecond = new ArrayList<Object>();
}
return this.firstAndSecond;
}
public Foo withFirstAndSecond(Object... values) {
if (values!= null) {
for (Object value: values) {
getFirstAndSecond().add(value);
}
}
return this;
}
public Foo withFirstAndSecond(Collection<Object> values) {
if (values!= null) {
getFirstAndSecond().addAll(values);
}
return this;
}
}
FirstType class :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "FirstType", propOrder = {
"val"
})
public class FirstType {
#XmlElement(required = true)
protected String val;
/**
* Gets the value of the val property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getVal() {
return val;
}
/**
* Sets the value of the val property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setVal(String value) {
this.val = value;
}
public FirstType withVal(String value) {
setVal(value);
return this;
}
}
SeconType class :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "SecondType", propOrder = {
"testval"
})
public class SecondType {
#XmlElement(required = true)
protected String testval;
/**
* Gets the value of the testval property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTestval() {
return testval;
}
/**
* Sets the value of the testval property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTestval(String value) {
this.testval = value;
}
public SecondType withTestval(String value) {
setTestval(value);
return this;
}
}
The unmarshalling works perfectly in JAXB :
String xml = "<foo>" + "<first><val>some</val></first><second><testval>test</testval></second>" + "</foo>";
Unmarshaller un = JAXBContext.newInstance(Foo.class).createUnmarshaller();
Foo unmarshal = (Foo) un.unmarshal(new StringReader(xml));
System.out.println(unmarshal.getFirstAndSecond());
System.out.println(unmarshal.getFirstAndSecond().size());
But it doesn't works with Jackson2 ...
I have done some research on the web, I have seen discussion about a bug in Jackson on handling XmlElements annotation
You see the link https://github.com/FasterXML/jackson-databind/issues/374
The solution was to make use of:
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
</dependency>
And using -Xsimplify during xsdtojava generation.
And define a binding for that element explicit:
<jaxb:bindings
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
jaxb:extensionBindingPrefixes="xjc simplify"
jaxb:version="2.1">
<jaxb:bindings schemaLocation="xsd/test.xsd">
<jaxb:bindings multiple="true" node="//xs:element[#name='foo']//xs:complexType//xs:sequence">
<simplify:as-element-property/>
</jaxb:bindings>
</jaxb:binding>
</jaxb:bindings>
This will generate two single elements, for each type:
private List<FirstType> firstType;
private List<SecondType> secondType;

Parsing #XmlAnyElement(lax = true) from soap response

I am trying to consume healthcare related webservice to validate DEA number. I have created client class using WSDL tool. I am providing the SOAP response and the client class generated by WSDL to handle SOAP response. Please provide solution to parse response XML . Especially #XmlAnyElement(lax = true) element.
Here is my response xml :
<?xml version="1.0" encoding="UTF-8"?>
<DataSet xmlns="http://tempuri.org/">
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="DEA">
<xs:complexType>
<xs:sequence>
<xs:element name="Dea" type="xs:string" minOccurs="0"/>
<xs:element name="BAC" type="xs:string" minOccurs="0"/>
<xs:element name="Drug_x0020_Schedule" type="xs:string" minOccurs="0"/>
<xs:element name="Expiration_x0020_Date" type="xs:dateTime" minOccurs="0"/>
<xs:element name="Company_x0020_Name" type="xs:string" minOccurs="0"/>
<xs:element name="Address_1" type="xs:string" minOccurs="0"/>
<xs:element name="Address_2" type="xs:string" minOccurs="0"/>
<xs:element name="Address_3" type="xs:string" minOccurs="0"/>
<xs:element name="Address_4" type="xs:string" minOccurs="0"/>
<xs:element name="State" type="xs:string" minOccurs="0"/>
<xs:element name="Zip_x0020_Code" type="xs:string" minOccurs="0"/>
<xs:element name="Drug_x0020_Codes" type="xs:string" minOccurs="0"/>
<xs:element name="BASC" type="xs:string" minOccurs="0"/>
<xs:element name="Payment_x0020_Indicator" type="xs:string" minOccurs="0"/>
<xs:element name="Activity" type="xs:string" minOccurs="0"/>
<xs:element name="siganture_date" type="xs:string" minOccurs="0"/>
<xs:element name="URL" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<DEA diffgr:id="DEA1" msdata:rowOrder="0">
<Dea>*******</Dea>
<BAC>C</BAC>
<Drug_x0020_Schedule>*******</Drug_x0020_Schedule>
<Expiration_x0020_Date>*******</Expiration_x0020_Date>
<Company_x0020_Name>*******</Company_x0020_Name>
<Address_1 xml:space="preserve"></Address_1>
<Address_2>*******</Address_2>
<Address_3 xml:space="preserve"></Address_3>
<Address_4>*******</Address_4>
<State>**</State>
<Zip_x0020_Code>****</Zip_x0020_Code>
<BASC>*</BASC>
<Payment_x0020_Indicator>*</Payment_x0020_Indicator>
<Activity>****</Activity>
<siganture_date>*****</siganture_date>
<URL/>
</DEA>
</NewDataSet>
</diffgr:diffgram>
</DataSet>
Here is my client class to handle response
package org.tempuri;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.w3._2001.xmlschema.Schema;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="GetQueryResult" minOccurs="0">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element ref="{http://www.w3.org/2001/XMLSchema}schema"/>
* <any/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"getQueryResult"
})
#XmlRootElement(name = "GetQueryResponse")
public class GetQueryResponse {
#XmlElement(name = "GetQueryResult")
protected GetQueryResponse.GetQueryResult getQueryResult;
/**
* Gets the value of the getQueryResult property.
*
* #return
* possible object is
* {#link GetQueryResponse.GetQueryResult }
*
*/
public GetQueryResponse.GetQueryResult getGetQueryResult() {
return getQueryResult;
}
/**
* Sets the value of the getQueryResult property.
*
* #param value
* allowed object is
* {#link GetQueryResponse.GetQueryResult }
*
*/
public void setGetQueryResult(GetQueryResponse.GetQueryResult value) {
this.getQueryResult = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element ref="{http://www.w3.org/2001/XMLSchema}schema"/>
* <any/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"schema",
"any"
})
public static class GetQueryResult {
#XmlElement(namespace = "http://www.w3.org/2001/XMLSchema", required = true)
protected Schema schema;
#XmlAnyElement(lax = true)
protected Object any;
/**
* Gets the value of the schema property.
*
* #return
* possible object is
* {#link Schema }
*
*/
public Schema getSchema() {
return schema;
}
/**
* Sets the value of the schema property.
*
* #param value
* allowed object is
* {#link Schema }
*
*/
public void setSchema(Schema value) {
this.schema = value;
}
/**
* Gets the value of the any property.
*
* #return
* possible object is
* {#link Object }
*
*/
public Object getAny() {
return any;
}
/**
* Sets the value of the any property.
*
* #param value
* allowed object is
* {#link Object }
*
*/
public void setAny(Object value) {
this.any = value;
}
}
}

XML Request Jaxb

I am trying to make a Java object out of an xml request using Jaxb but my limited knowledge of jaxb is holding me back. I have done this before but it was with simple XML documents only using basic Elements such as
<RootElement>
<Bookname>Moby Dick</Bookname>
<BookCode>1</BookCode>
</RootElement>
But now I have a bit more complicated of an xml file and any help getting me started on how to create this object would be greatly appreciated. I think I will have to use some sort of list, along with #Xmlattribute, but am just confused at the moment. Any help would be greatly appreciated! I hope I am not just overthinking this. The sample XML is found below:
<?xml version="1.0"?>
<CRMMessage language="en_US" currency="USD" >
<RequestSource name="Testsource" version="2" />
<RequestCode>GetTest</RequestCode>
<DataSet>
<DataSetColumns>
<DSColumn name="Column1" />
<DSColumn name="Column2" />
</DataSetColumns>
<Rows>
<Row>
<Col>John</Col>
<Col>Doe</Col>
</Row>
</Rows>
</DataSet>
</CRMMessage>
I have knocked you up a quick schema, this may not be exactly what you need as I cannot tell from the example data whether more than one or certain elements it allowed etc:
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="CRMMessage">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="RequestSource">
<xs:complexType>
<xs:attribute name="Testsource" type="xs:string"/>
<xs:attribute name="version" type="xs:integer"/>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="1" name="RequestCode" type="xs:string"/>
<xs:element minOccurs="1" maxOccurs="1" name="DataSet">
<xs:complexType>
<xs:all>
<xs:element minOccurs="1" maxOccurs="1" name="DataSetColumns">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="DSColumn">
<xs:complexType>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="1" maxOccurs="1" name="Rows">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Row">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Col" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="language" type="xs:string"/>
<xs:attribute name="currency" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:schema>
You should be able to use that as a starting point.
I then compiled that into a class using xjc via the maven plugin and the following in my pom:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.2</version>
<executions>
<execution>
<id>bind-crm</id>
<configuration>
<schemaDirectory>src/main/resources/</schemaDirectory>
<generatePackage>com.my.package.crm</generatePackage>
<forceRegenerate>true</forceRegenerate>
</configuration>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
This gave me the following code:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"requestSource",
"requestCode",
"dataSet"
})
#XmlRootElement(name = "CRMMessage")
public class CRMMessage {
#XmlElement(name = "RequestSource", required = true)
protected CRMMessage.RequestSource requestSource;
#XmlElement(name = "RequestCode", required = true)
protected String requestCode;
#XmlElement(name = "DataSet", required = true)
protected CRMMessage.DataSet dataSet;
#XmlAttribute(name = "language")
protected String language;
#XmlAttribute(name = "currency")
protected String currency;
/**
* Gets the value of the requestSource property.
*
* #return
* possible object is
* {#link CRMMessage.RequestSource }
*
*/
public CRMMessage.RequestSource getRequestSource() {
return requestSource;
}
/**
* Sets the value of the requestSource property.
*
* #param value
* allowed object is
* {#link CRMMessage.RequestSource }
*
*/
public void setRequestSource(CRMMessage.RequestSource value) {
this.requestSource = value;
}
/**
* Gets the value of the requestCode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getRequestCode() {
return requestCode;
}
/**
* Sets the value of the requestCode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setRequestCode(String value) {
this.requestCode = value;
}
/**
* Gets the value of the dataSet property.
*
* #return
* possible object is
* {#link CRMMessage.DataSet }
*
*/
public CRMMessage.DataSet getDataSet() {
return dataSet;
}
/**
* Sets the value of the dataSet property.
*
* #param value
* allowed object is
* {#link CRMMessage.DataSet }
*
*/
public void setDataSet(CRMMessage.DataSet value) {
this.dataSet = value;
}
/**
* Gets the value of the language property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getLanguage() {
return language;
}
/**
* Sets the value of the language property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setLanguage(String value) {
this.language = value;
}
/**
* Gets the value of the currency property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getCurrency() {
return currency;
}
/**
* Sets the value of the currency property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setCurrency(String value) {
this.currency = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <all>
* <element name="DataSetColumns">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="DSColumn" maxOccurs="unbounded">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* <element name="Rows">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Row" maxOccurs="unbounded">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Col" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </all>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
})
public static class DataSet {
#XmlElement(name = "DataSetColumns", required = true)
protected CRMMessage.DataSet.DataSetColumns dataSetColumns;
#XmlElement(name = "Rows", required = true)
protected CRMMessage.DataSet.Rows rows;
/**
* Gets the value of the dataSetColumns property.
*
* #return
* possible object is
* {#link CRMMessage.DataSet.DataSetColumns }
*
*/
public CRMMessage.DataSet.DataSetColumns getDataSetColumns() {
return dataSetColumns;
}
/**
* Sets the value of the dataSetColumns property.
*
* #param value
* allowed object is
* {#link CRMMessage.DataSet.DataSetColumns }
*
*/
public void setDataSetColumns(CRMMessage.DataSet.DataSetColumns value) {
this.dataSetColumns = value;
}
/**
* Gets the value of the rows property.
*
* #return
* possible object is
* {#link CRMMessage.DataSet.Rows }
*
*/
public CRMMessage.DataSet.Rows getRows() {
return rows;
}
/**
* Sets the value of the rows property.
*
* #param value
* allowed object is
* {#link CRMMessage.DataSet.Rows }
*
*/
public void setRows(CRMMessage.DataSet.Rows value) {
this.rows = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="DSColumn" maxOccurs="unbounded">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"dsColumn"
})
public static class DataSetColumns {
#XmlElement(name = "DSColumn", required = true)
protected List<CRMMessage.DataSet.DataSetColumns.DSColumn> dsColumn;
/**
* Gets the value of the dsColumn 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 object.
* This is why there is not a <CODE>set</CODE> method for the dsColumn property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getDSColumn().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link CRMMessage.DataSet.DataSetColumns.DSColumn }
*
*
*/
public List<CRMMessage.DataSet.DataSetColumns.DSColumn> getDSColumn() {
if (dsColumn == null) {
dsColumn = new ArrayList<CRMMessage.DataSet.DataSetColumns.DSColumn>();
}
return this.dsColumn;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
public static class DSColumn {
#XmlAttribute(name = "name")
protected String name;
/**
* Gets the value of the name property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setName(String value) {
this.name = value;
}
}
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Row" maxOccurs="unbounded">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Col" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"row"
})
public static class Rows {
#XmlElement(name = "Row", required = true)
protected List<CRMMessage.DataSet.Rows.Row> row;
/**
* Gets the value of the row 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 object.
* This is why there is not a <CODE>set</CODE> method for the row property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getRow().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link CRMMessage.DataSet.Rows.Row }
*
*
*/
public List<CRMMessage.DataSet.Rows.Row> getRow() {
if (row == null) {
row = new ArrayList<CRMMessage.DataSet.Rows.Row>();
}
return this.row;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Col" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"col"
})
public static class Row {
#XmlElement(name = "Col", required = true)
protected List<String> col;
/**
* Gets the value of the col 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 object.
* This is why there is not a <CODE>set</CODE> method for the col property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getCol().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link String }
*
*
*/
public List<String> getCol() {
if (col == null) {
col = new ArrayList<String>();
}
return this.col;
}
}
}
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <attribute name="Testsource" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="version" type="{http://www.w3.org/2001/XMLSchema}integer" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
public static class RequestSource {
#XmlAttribute(name = "Testsource")
protected String testsource;
#XmlAttribute(name = "version")
protected BigInteger version;
/**
* Gets the value of the testsource property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTestsource() {
return testsource;
}
/**
* Sets the value of the testsource property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTestsource(String value) {
this.testsource = value;
}
/**
* Gets the value of the version property.
*
* #return
* possible object is
* {#link BigInteger }
*
*/
public BigInteger getVersion() {
return version;
}
/**
* Sets the value of the version property.
*
* #param value
* allowed object is
* {#link BigInteger }
*
*/
public void setVersion(BigInteger value) {
this.version = value;
}
}
}
That help?
Creating an XML schema for your XML and generating a model from it is definitely as answered by bmorris591 is definitely one way to go. But your XML document isn't so complicated that you can't start from objects.
CRMMessage
We use the #XmlRootElement annotation to map our root object to the root element of the document.
By default JAXB (JSR-222) implementations look for metadata on the public properties (get/set methods). To save space I have set #XmlAccessorType(XmlAccessType.FIELD) to specify that the metadata is on the fields (see: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html)
The #XmlAttribute annotation is used to specify that a field/property maps to an XML attribute.
By default all fields/properties map to XML elements. If the default XML name does not match your desired mapping then you can use the #XmlElement annotation to override the name.
import javax.xml.bind.annotation.*;
#XmlRootElement(name="CRMMessage")
#XmlAccessorType(XmlAccessType.FIELD)
public class CRMMessage {
#XmlAttribute
private String language;
#XmlAttribute
private String currency;
#XmlElement(name="RequestCode")
private String requestCode;
#XmlElement(name="DataSet")
private DataSet dataSet;
}
DataSet
One advantage of starting from Java classes is that you can leverage the #XmlElementWrapper annotation to add a grouping element on your collection fields/properties (see: http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html). Compare this with the generated DataSet class https://stackoverflow.com/a/14986770/383861.
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
public class DataSet {
#XmlElementWrapper(name="DataSetColumns")
#XmlElement(name="DSColumn")
private List<DSColumn> columns;
#XmlElementWrapper(name="Rows")
#XmlElement(name="Row")
private List<Row> rows;
}

How can i unmarshal with JAXB

I have some problem when unmarshaling a .xml at a web service using JAXB.
This is the .xml file being sent from some client to the web service.
<?xml version="1.0" encoding="UTF-8"?>
<PERSON xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:/D:/MyWorkSpace/JAVA%20WEB%20Services%20DEVELOPER/XML%20Workspace/Persons.xsd">
<NAME>Michael</NAME>
<AGE>12</AGE>
<ADRESS>
<STREET>Somewhere in Spain</STREET>
<ZIP>47015</ZIP>
</ADRESS>
<HOBY indoorHoby="true"/>
</PERSON>
This is the method that does the unmarshaling
#POST
#Path("/XMLArrivalBeacon")
#Consumes(MediaType.APPLICATION_XML)
public Response methodI(String content) {
System.out.print(content);
try {
//Unmarshaling
JAXBContext context = JAXBContext.newInstance(Person.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
//Unmarshal the String
Person person = (Person) unmarshaller.unmarshal(new StreamSource(new StringReader(content)));
//Checking that the values were recieved ok
System.out.print(person.getName());
return Response.ok("XML recieved from client!!!").build();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Here is the person class annotated with the JAXB annotations(Was automatically generated from the Schema)
package bindedschemas;
import java.math.BigInteger;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="age">
* <simpleType>
* <restriction base="{http://www.w3.org/2001/XMLSchema}integer">
* <minInclusive value="18"/>
* </restriction>
* </simpleType>
* </element>
* <element name="address">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="street" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="zip" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* <attribute name="country" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </element>
* <element name="hobie">
* <simpleType>
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
* </restriction>
* </simpleType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"name",
"age",
"address",
"hobie"
})
#XmlRootElement(name = "Person")
public class Person {
#XmlElement(required = true)
protected String name;
#XmlElement(required = true)
protected BigInteger age;
#XmlElement(required = true)
protected Person.Address address;
#XmlElement(required = true)
protected String hobie;
/**
* Gets the value of the name property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setName(String value) {
this.name = value;
}
/**
* Gets the value of the age property.
*
* #return
* possible object is
* {#link BigInteger }
*
*/
public BigInteger getAge() {
return age;
}
/**
* Sets the value of the age property.
*
* #param value
* allowed object is
* {#link BigInteger }
*
*/
public void setAge(BigInteger value) {
this.age = value;
}
/**
* Gets the value of the address property.
*
* #return
* possible object is
* {#link Person.Address }
*
*/
public Person.Address getAddress() {
return address;
}
/**
* Sets the value of the address property.
*
* #param value
* allowed object is
* {#link Person.Address }
*
*/
public void setAddress(Person.Address value) {
this.address = value;
}
/**
* Gets the value of the hobie property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getHobie() {
return hobie;
}
/**
* Sets the value of the hobie property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setHobie(String value) {
this.hobie = value;
}
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="street" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="zip" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* <attribute name="country" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"street",
"zip"
})
public static class Address {
#XmlElement(required = true)
protected String street;
#XmlElement(required = true)
protected String zip;
#XmlAttribute(name = "country")
protected String country;
/**
* Gets the value of the street property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getStreet() {
return street;
}
/**
* Sets the value of the street property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setStreet(String value) {
this.street = value;
}
/**
* Gets the value of the zip property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getZip() {
return zip;
}
/**
* Sets the value of the zip property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setZip(String value) {
this.zip = value;
}
/**
* Gets the value of the country property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getCountry() {
return country;
}
/**
* Sets the value of the country property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setCountry(String value) {
this.country = value;
}
}
}
And this is the exception i get
SEVERE: javax.xml.bind.UnmarshalException: unexpected element (uri:"",
local:"PERSON"). Expected elements are <{}Person> at
com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
at
com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
at
com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
Any idea how can i fix it?
Your xml does not match your schema. xml element names are case sensitive. "PERSON" and "Person" are not the same element.

Categories

Resources