Key and Keyref Elements
HydraExpress provides limited support for the key and keyref schema elements. These schema elements serve two main purposes:
referencing an element defined by a
key using a
keyrefguaranteeing uniqueness of the value or set of values defined by a
keyThe HydraExpress implementation supports only the first purpose. Uniqueness of the values defined by the key element is not guaranteed. Furthermore, the XML Schema element unique, whose sole purpose is to guarantee uniqueness of a set of values, is not supported in any way.
To understand the key and keyref elements, let’s take as an example the purchase order schema’s Items element:
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="productName" type="xsd:string"/>
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="USPrice" type="xsd:decimal"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="partNum" type="SKU" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
The Items element contains a sequence of item elements. These elements contain information about the purchase of a particular item in a particular purchase order. But perhaps this information is not sufficient to determine whether it is possible to fulfill the order. For example, there is no information about the number of such items currently held in inventory. How can we access this additional information?
There might exist another datatype called Inventory, which also has an Items element containing a sequence of item elements. The Inventory contains item elements for every product the company sells, and these elements might contain much more information than the item elements in the purchase order. It would be convenient, therefore, to have an easy way to access the corresponding inventory item element from a purchase order item.
We could create a keyref like this:
<key name="inventoryItems">
<selector xpath="Inventory/Items/item"/>
<field xpath="@partNum"/>
</key>
The XPath expression defined by the xpath attribute of the selector element produces a result node set of all the item elements in the Inventory. The xpath attribute of the field element specifies the value used to access a particular item element in the result node set. Of course, to be sure of getting the right item element, the attribute value partNum should be unique, but keep in mind that HydraExpress does not guarantee this uniqueness.
The items in a PurchaseOrder could then be linked to items in the Inventory through a keyref:
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items">
<keyref name="poItems" refer="inventoryItems">
<selector xpath="item"/>
<field xpath="@partNum"/>
</keyref>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
For each
keyref, HydraExpress generates a
getnameKeyRef() and a
setnameKeyRef() method. For the above example, these would be
getpoItemsKeyRef() and
setpoItemsKeyRef() methods. The
get method would return the corresponding
item from
Inventory, as a
rwsf::XmlBindingHandle instance. This object could be used to retrieve inventory data useful in processing the purchase order. The
set method sets the
item in
Inventory to the
rwsf::XmlBindingHandle instance provided. This might be used, for example, to change the
item instance in the
Inventory to reflect the new value for quantity on hand after deducting the number of items needed to fulfill the purchase order.