Monday, 6 October 2014

populating a list attribute



I have an entity ADXP which contains two properties, including a String called content and a List<String> called partType. These ADXP entities are parts of an address entity AD, so that each part of the address has its content in a string and its part type(s) in a List<String>. For example, the xml content might look like this:



<organization>
<id root="1.23.245.7.890"/>
<name>some name</name>
<telecom value="tel:+1-555-555-5000" use="HP"/>
<addr>
<streetAddressLine>123 Some Avenue</streetAddressLine>
<city>MyTown</city>
<state>AState</state>
<postalCode>98765</postalCode>
<country>US</country>
</addr>
</organization>


The address portion of the above xml should be populated into an AD java entity that has properties of type ADXP for streetAddressLine, city, state, postalCode, and country. For example, the AD.city property would be an ADXP object with content="MyTown" and partType containing a string entry "city". The problem is that JAXB is setting up separate entities for each part type, which each extend ADXP instead of setting up one ADXP and populating the partType property to reflect each type. I will include the xsd code starting with the top level Organization complex type:



<xs:complexType name="Organization">
<xs:sequence>
<xs:element name="id" type="II" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="name" type="ON" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="telecom" type="TEL" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="addr" type="AD" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="nullFlavor" type="NullFlavor" use="optional"/>
<xs:attribute name="classCode" type="EntityClassOrganization" use="optional" fixed="ORG"/>
</xs:complexType>


The AD complex type is defined by:



<xs:complexType name="AD">
<xs:annotation>
<xs:documentation>
Mailing and home or office addresses. A sequence of
address parts, such as street or post office Box, city,
postal code, country, etc.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="delimiter" type="adxp.delimiter"/>
<xs:element name="country" type="adxp.country"/>
<xs:element name="state" type="adxp.state"/>
<xs:element name="city" type="adxp.city"/>
<xs:element name="postalCode" type="adxp.postalCode"/>
<xs:element name="streetAddressLine" type="adxp.streetAddressLine"/>
</xs:sequence>
<xs:attribute name="use" use="optional" type="set_PostalAddressUse">
<xs:annotation>
<xs:documentation>
A set of codes advising a system or user which address
in a set of like addresses to select for a given purpose.
</xs:documentation>
</xs:annotation>
</xs:attribute>


You can see above that all of the elements are of subtypes of ADXP, when they should be of type ADXP. Here is the complex type definition for ADXP:



<xs:complexType name="ADXP" mixed="true">
<xs:annotation>
<xs:documentation>
A character string that may have a type-tag signifying its
role in the address. Typical parts that exist in about
every address are street, house number, or post box,
postal code, city, country but other roles may be defined
regionally, nationally, or on an enterprise level (e.g. in
military addresses). Addresses are usually broken up into
lines, which are indicated by special line-breaking
delimiter elements (e.g., DEL).
</xs:documentation>
</xs:annotation>
<xs:attribute name="partType" type="AddressPartType">
<xs:annotation>
<xs:documentation>
Specifies whether an address part names the street,
city, country, postal code, post box, etc. If the type
is NULL the address part is unclassified and would
simply appear on an address label as is.
</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>


Each of the address part type complex types are defined as follows. This may be what is causing the problem:



<xs:complexType mixed="true" name="adxp.delimiter">
<xs:complexContent>
<xs:restriction base="ADXP">
<xs:attribute name="partType" type="AddressPartType" fixed="DEL"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType mixed="true" name="adxp.country">
<xs:complexContent>
<xs:restriction base="ADXP">
<xs:attribute name="partType" type="AddressPartType" fixed="CNT"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType mixed="true" name="adxp.state">
<xs:complexContent>
<xs:restriction base="ADXP">
<xs:attribute name="partType" type="AddressPartType" fixed="STA"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType mixed="true" name="adxp.city">
<xs:complexContent>
<xs:restriction base="ADXP">
<xs:attribute name="partType" type="AddressPartType" fixed="CTY"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType mixed="true" name="adxp.postalCode">
<xs:complexContent>
<xs:restriction base="ADXP">
<xs:attribute name="partType" type="AddressPartType" fixed="ZIP"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType mixed="true" name="adxp.streetAddressLine">
<xs:complexContent>
<xs:restriction base="ADXP">
<xs:attribute name="partType" type="AddressPartType" fixed="SAL"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>


This is generating the following AD class in java:



@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AD", propOrder = {"delimiter","country","state","city","postalCode","streetAddressLine","useablePeriod"
})
public class AD {

@XmlElement(required = true)
protected AdxpDelimiter delimiter;
@XmlElement(required = true)
protected AdxpCountry country;
@XmlElement(required = true)
protected AdxpState state;
@XmlElement(required = true)
protected AdxpCity city;
@XmlElement(required = true)
protected AdxpPostalCode postalCode;
@XmlElement(required = true)
protected AdxpStreetAddressLine streetAddressLine;
protected List<SXCMTS> useablePeriod;
@XmlAttribute(name = "use")
protected List<String> use;

//getters and setters
}


And the following ADXP class:



@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ADXP", propOrder = {"content"})
@XmlSeeAlso({AdxpDelimiter.class,AdxpStreetAddressLine.class,AdxpCountry.class,AdxpState.class,AdxpCity.class,AdxpPostalCode.class})
public class ADXP {

@XmlValue
protected String content;
@XmlAttribute(name = "partType")
protected List<String> partType;

//getters and setters
}


And then each of the classes in @XmlSeeAlso above simply extend ADXP without adding any methods.


How can I change the xsd definitions so that the properties of type AD are all of type ADXP, without creating any subentities? And so that the partType property of each ADXP object is automatically populated with the correct property type string? (e.g. city, state, postalcode, etc.)


No comments:

Post a Comment