- From: Brian Maso <brian@blumenfeld-maso.com>
- Date: Wed, 10 Sep 2003 14:23:11 -0700
- To: www-ql@w3.org
(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