- 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