Re: Comparing relationships XML vs. RDBs

(Responding to myself)

[snip]

 > Use XML Schemas, there is no standard way to represent a relationship 
between an element located
 > in document A to an element in document B. The only intra-element 
relationships are within the
 > same document. Specifically, the usable relationships are the XPath axes 
(child::, parent::,
 > attribute::, etc.) So intra-entity relationships in XML Schemas seem a 
bit weaker to me than in
 > relational schemas.

Re-reading "Essential XML Quick Reference" (Skonnard, Gudgin) chapter on 
XML Schema I realize using <xs:key> and <xs:keyref> elements that XML 
Schema supports intra-element references within the same document. However 
you can't reference between documents, and XPath doesn't have any support 
for these keyref-based references.

The following schema describes a relationship between top-level order 
elements and item elements, expressed in individual order-item elements 
that are children of the order elements.

<xs:complexType name="itemType">
   <xs:complexContent>
     <xs:sequence>
       <xs:element name="name" type="xs:string"/>
       ... <!-- description, supplier, etc. --> ...
     </xs:sequence>
     <xs:attribute name="id" type="ID" use="required"/>
   </xs:complexContent>
</xs:complexType>

<xs:complexType name="orderType">
   <xs:complexContent>
     <xs:sequence>
       ... <!-- order number, salesperson, etc. --> ...
       <xs:element name="order-item" type="tns:orderItemType"
           minOccurs="0" maxOccurs="1"/>
     </xs:sequence>
   </xs:complexContent>
</xs:complexType>

<xs:complexType name="orderItemType">
   <xs:complexContent>
     <xs:sequence>
       <xs:elemenmt name="quantity" type="xs:nonNegativeInteger"/>
       ... <!-- color or other options, extra notes, etc. --> ...
     </xs:sequence>
     <xs:attribute name="itemID" type="ID"/>
   </xs:complexContent>
</xs:complexType>

<xs:element name="items-and-orders">
   <xs:complexContent>
     <xs:sequence>
       <xs:element name="item" type="itemType"
               minOccurs="0" maxOccurs="unbounded"/>
       <xs:element name="order" type="orderType"
               minOccurs="0" maxOccurs="unbounded"/>
     </xs:sequence>
   </xs:complexContent>

   <xs:key name="keyItemID">
     <xs:selector xpath="item"/>
     <xs:field xpath="@id"/>
   </xs:key>

   <xs:keyref name="OrderItem_to_Item" refer="keyItemID>
     <xs:selector xpath="order/order-item"/>
     <xs:field xpath="@itemID">
   </xs:keyref>
</xs:element>

XQuery main module listing each item name along with the number of items 
ordered (off the cuff, probably OK -- enough to get the gist):

for $item in (/items-and-orders/item)
let $itemID = $item/@id/value(), $itemName=$item/name/value()
return
   (
    $itemName, ": ",
    fn:sum(/items-and-orders/order/order-item[@itemID = 
$itemID]/quantity/value()),
    "\n")
   )

The relationship between order-item and the item it refers to is buried in 
the "[@itemID = $itemID]" XPath predicate. (No way to simply use the 
"OrderItem_to_Item" keyref defined in the schema.)

Using nested FLOWR expressions I guess I could do the same thing like so:

for $item in (/items-and-orders/item)
for $order-item in (/items-and-orders/order/order-item)
where ($item/@id/value() = $order-item/@itemID/value())
return
   (
    $item/name/value(), ": ",
    fn:sum($order-item/quantity/value()),
    "\n")
   )

This "feels" a lot more SQL-y. But its a completely synthetic example: I 
wouldn't keep items and orders all in the same document. What would be a 
"good" way to define my XML DB? Create a collection of "item" documents, 
one item per document? Create a single "items" document holding all "item" 
elements? Create a collection of "order" documents? Or a single "orders" 
document with multiple "order" elements under it? In any of these cases I 
wouldn't be able to define the key/keyref combo that defines the constraint 
on order-item/@itemID values.

Any thoughts on how to define the key/keyref with items and orders stored 
in separate documents?

Brian Maso

Received on Thursday, 11 September 2003 10:10:36 UTC