4.7 Polymophic relations
SData schemas MAY contain polymorphic relations between resource kinds. A polymorphic relation is a relation that targets resources of more than one kind.
A typical example is the relationship between a receipt line and its originator document. The originator document may be either a sales invoice, as sales order, a purchase credit or a purchase return.
In this example, the relationship property is defined as follows:
<xs:element name="originatorDocument" type="receiptOriginatorDocument--choice" nillable="true" minOccurs="0" sme:relationship="reference" sme:isCollection="false">
If the polymorphic relation is not a collection, the type name of the element SHOULD be postfixed by –choice, as in the example just above. The type itself MUST be defined as an XSD choice type. For example:
<xs:complexType name="receiptOriginatorDocument--choice"> <xs:choice minOccurs="0"> <xs:element name="salesInvoice" type="salesInvoice--type"/> <xs:element name="salesOrder" type="salesOrder--type"/> <xs:element name="purchaseCredit" type="purchaseCredit--type"/> <xs:element name="purchaseReturn" type="purchaseReturn--type"/> </xs:choice> </xs:complexType>
With this XSD definition, a typical payload will look like:
<receipt sdata:uuid="37b1..." sdata:url="http://..."> <date>2011-01-27</date> ... <originatorDocument> <salesOrder sdata:uuid="903e..." sdata:url="http://..."/> </originatorDocument> </receipt>
Unlike an ordinary reference which takes only one element in the payload, a polymorphic reference is encoded with two elements: a first element tagged with the property name (<originatorDocument>) and a second element tagged with the type of the referenced resource (<salesOrder>).
If the polymorphic relation is a collection, the type name SHOULD be postfixed by –list, as usual, and the type MUST be defined as an unbounded choice type.
<xs:complexType name="receiptOriginatorDocument--list"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="salesInvoice" type="salesInvoice--type"/> <xs:element name="salesOrder" type="salesOrder--type"/> <xs:element name="purchaseCredit" type="purchaseCredit--type"/> <xs:element name="purchaseReturn" type="purchaseReturn--type"/> </xs:choice> </xs:complexType>
If we assumed that a receipt could have several originator documents, it would have an originatorDocuments (plural) property in the schema, of type receiptOriginatoryDocument–list. A typical payload would then be:
<receipt sdata:uuid="37b1..." sdata:url="http://..."> <date>2011-01-27</date> ... <originatorDocuments> <salesOrder sdata:uuid="903e..." sdata:url="http://..."/> <salesInvoice sdata:uuid="077b..." sdata:url="http://..."/> ... </originatorDocuments> </receipt>
In this example, the list is polymorphic as it mixes elements of different types (salesOrder, salesInvoice). Like in the previous example, the XML markup has two levels: a first level tagged with the property name (<originatorDocuments>) and a second level tagged with the types of the referenced resources (<salesOrder>, <salesInvoice>).
SData providers SHOULD follow the naming convention described above for their polymorphic types. They MUST use define the XSD complexType as a choice type, as described above.