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

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;

Related

JAXB - XJC - Mapping XML Encryption schema into Java classes

I'm trying to map the XML Schema for XML Encryption into Java classes to be used with JAXB (https://www.w3.org/TR/xmlenc-core/xenc-schema.xsd), using XJC.
I am a bit puzzled by the mapping of the EncryptionMethodType type. In the schema, it is defined as
<complexType name='EncryptionMethodType' mixed='true'>
<sequence>
<element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/>
<element name='OAEPparams' minOccurs='0' type='base64Binary'/>
<any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</sequence>
<attribute name='Algorithm' type='anyURI' use='required'/>
</complexType>
XJC generates the following type (comments removed for brevity):
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "EncryptionMethodType", propOrder = {
"content"
})
public class EncryptionMethodType {
#XmlElementRefs({
#XmlElementRef(name = "KeySize", namespace = "http://www.w3.org/2001/04/xmlenc#", type = JAXBElement.class, required = false),
#XmlElementRef(name = "OAEPparams", namespace = "http://www.w3.org/2001/04/xmlenc#", type = JAXBElement.class, required = false)
})
#XmlMixed
#XmlAnyElement(lax = true)
protected List<Object> content;
#XmlAttribute(name = "Algorithm", required = true)
#XmlSchemaType(name = "anyURI")
protected String algorithm;
/**
* Objects of the following type(s) are allowed in the list
* {#link JAXBElement }{#code <}{#link BigInteger }{#code >}
* {#link JAXBElement }{#code <}{#link byte[]}{#code >}
* {#link String }
* {#link Object }
*/
public List<Object> getContent() {
if (content == null) {
content = new ArrayList<Object>();
}
return this.content;
}
public String getAlgorithm() {
return algorithm;
}
public void setAlgorithm(String value) {
this.algorithm = value;
}
}
I am not a JAXB expert (and the documentation is sparse and mostly terrible), but since the KeySize and the OAEPparams elements have cardinality 0 or 1, I was expecting them to become separate properties in the Java code, leaving the List<Object> for the unbounded ##other elements.
Is there any parameter or custom bindings I can apply to get a simpler Java representation, i.e. like this one?
class EncryptionMethodType {
public BigInteger KeySize;
public byte[] OAEPparams;
public List<Object> otherContent;
}
Thanks in advance!

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 ?

JAXB returns null when Xml does not include a tag

I am having a problem with JAXB and Unmarshalling the following XML
<ns2:ID entry-method="manual"> 123456789012345678
<ns2:ID2>123456789012345678</ns2:ID2>
</ns2:ID>
I obtained the schema and using the the JAXB xjc tool it generated the following property definition:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"ID1",
"ID2",
"ID3"
})
#XmlRootElement(name = "ID")
public class ID {
#XmlElement(name = "ID1")
protected String id1;
#XmlElement(name = "ID2")
protected String id2;
#XmlElement(name = "ID3")
protected String id3;
#XmlAttribute(name = "entryMethod")
protected String entryMethod;
public String getId1() {
return id1
}
public void setId1(String value) {
this.id1 = value;
}
public String getId2() {
return id2
}
public void setId2(String value) {
this.id2 = value;
}
public String getId3() {
return id3;
}
public void setId3(String value) {
this.id3 = value;
}
public String getEntryMethod() {
if (entryMethod == null) {
return "swipe";
} else {
return entryMethod;
}
}
public void setEntryMethod(String value) {
this.entryMethod = value;
}
}
As you can see the device that is sending the XML does not include the ID1 tag it merely adds the ID1 data as the value of the root tag. When Unmarshalling this Xml any calls to getID1 return null. I am confused on what annotations to use to alter the class to support the data in the root tag to be assigned to the id1 field.
Any ideas on what annotation changes would make this work?
Tim
This is the correct XML schema content (omitting namespace) for your XML:
<xs:element name="ID" type="IdType"/>
<xs:complexType name="IdType" mixed="true">
<xs:sequence>
<xs:element name="id2" type="xs:string"/>
<xs:element name="id3" type="xs:string"/>
</xs:sequence>
<xs:attribute name="entry-method" type="xs:string"/>
</xs:complexType>
The sad consequence is that the generated class IdType contains
public List<Serializable> getContent() {
if (content == null) {
content = new ArrayList<Serializable>();
}
return this.content;
}
for containing the ID text child (children!) and all the ID element children. So, the processing of an ID might be something like:
JAXBElement<IdType> jbe =
(JAXBElement<IdType>)u.unmarshal( new File( "mixed.xml" ) );
for( Object obj: jbe.getValue().getContent() ){
System.out.println( obj.getClass() + " " + obj );
if( obj instanceof String ){
// text child (even the blank space
} else if( obj instanceof JAXBElement ){
// process an element child wrapped into JAXBElement
}
}
Why You Are Getting Null
The XML you are unmarshalling does not match the XML Schema that you generated the object model from.
<ns2:ID entry-method="manual"> 123456789012345678
<ns2:ID2>123456789012345678</ns2:ID2>
</ns2:ID>
The Problem
When an element has both text and element it is said to have mixed content. Your XML schema does not currently account for this.
The Solution
Change the definition of the complex type corresponding to the ID element to have mixed="true". Then regenerate your JAXB model.
Why You Won't Like The Solution
Since a type with mixed content scattered among the child elements you are going to get a very different JAXB model. Essentially the class for ID is going to have one List property that contains all the content. This is necessary to be able to find trip the XML.
Your ID class should be ...
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"content"
})
#XmlRootElement(name = "ID")
public class ID {
#XmlElementRefs({
#XmlElementRef(name = "ID3", type = JAXBElement.class),
#XmlElementRef(name = "ID2", type = JAXBElement.class),
#XmlElementRef(name = "ID1", type = JAXBElement.class)
})
#XmlMixed
protected List<Serializable> content;
#XmlAttribute(name = "entry-method")
protected String entryMethod;
/**
* Gets the value of the content 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 content property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getContent().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link String }
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
*
*
*/
public List<Serializable> getContent() {
if (content == null) {
content = new ArrayList<Serializable>();
}
return this.content;
}
/**
* Gets the value of the entryMethod property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getEntryMethod() {
return entryMethod;
}
/**
* Sets the value of the entryMethod property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setEntryMethod(String value) {
this.entryMethod = value;
}
}
I tried this bean with this main method...
public static void main(String[] args) throws JAXBException {
final JAXBContext context = JAXBContext.newInstance(ID.class);
final Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final ID id = new ID();
id.setEntryMethod("method");
ObjectFactory o = new ObjectFactory();
id.getContent().add("sample text");
id.getContent().add(o.createIDID1("id1"));
m.marshal(id, System.out);
}
The output generates is..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ID entry-method="method">sample text
<ID1>id1</ID1>
</ID>
I hope I've given you all the answers about your question.

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;
}

Restricting XML attribute to enum values

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);
}
}

Categories

Resources