My java classes are being generated from xsd file.
The goal I want to accomplish is to have some "known" properties based on the type of elements. For instance, I have a list of animals. After the xml is being parsed, I want to know in the code how many legs have my animals. But the number of legs is a characteristic of the animal type, so, in case I have a cat it will have 4 legs and the kangaroo will have 2 legs.
In case I define the xsd like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Animals" type="animals" />
<xs:complexType name="animals">
<xs:sequence>
<xs:element name="Animal" maxOccurs="unbounded" type="animal"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="animal" abstract="true">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="catType">
<xs:simpleContent>
<xs:extension base="animal">
<xs:attribute name="nbOfLegs" type="xs:integer" fixed="4" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="kangarooType">
<xs:simpleContent>
<xs:extension base="animal">
<xs:attribute name="nbOfLegs" type="xs:integer" fixed="2" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
The generated classes are as expected (I removed the annotations):
public abstract class Animal {
protected String name;
public String getName() {return name;}
public void setName(String value) {this.name = value;}
}
public class CatType extends Animal {
protected BigInteger nbOfLegs;
public BigInteger getNbOfLegs() {
if (nbOfLegs == null) {
return new BigInteger("4");
} else {
return nbOfLegs;
}
}
public void setNbOfLegs(BigInteger value) {this.nbOfLegs = value;}
}
This way, in case the user sets the number of legs for cats in the xml, it can only be 4, and if he doesn't, in code I will receive 4 anyway. Similar for kangaroo I always receive 2 legs.
But the problem with this approach is that I cannot use polymoprhism like this:
for(Animal animal : animals) {
System.out.println(animal.getNbOfLegs());
}
So I tried a different approach:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Animals" type="animals" />
<xs:complexType name="animals">
<xs:sequence>
<xs:element name="Animal" maxOccurs="unbounded" type="animal"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="animal" abstract="true">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" />
<xs:attribute name="nbOfLegs" type="xs:integer"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="catType">
<xs:simpleContent>
<xs:restriction base="animal">
<xs:attribute name="nbOfLegs" type="xs:integer" fixed="4" />
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="kangarooType">
<xs:simpleContent>
<xs:restriction base="animal">
<xs:attribute name="nbOfLegs" type="xs:integer" fixed="2" />
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
The Animal class is generated as expected:
public abstract class Animal {
protected String name;
protected BigInteger nbOfLegs;
public String getName() {return name;}
public void setName(String value) {this.name = value;}
public BigInteger getNbOfLegs() {return nbOfLegs;}
public void setNbOfLegs(BigInteger value) {this.nbOfLegs = value;}
}
But the generated CatType is empty.
I expected it to be like this:
public class CatType extends Animal {
@Override
public BigInteger getNbOfLegs() {
if (nbOfLegs == null) {
return new BigInteger("4");
} else {
return nbOfLegs;
}
}
}
Is it possible to customize the bindings file in order to achieve the desired generated CatType class?
Thank you.