XML - Managing Data Exchange/Recursive relationships
XML - Managing Data Exchange
|
Related Topics
|
Get Involved
|
Previous Chapter | Next Chapter |
← The many-to-many relationship | Data schemas → |
Learning objectives
|
Introduction
editRecursive relationships are an interesting and more complex concept than the relationships you have seen in the previous chapters. A recursive relationship occurs when there is a relationship between an entity and itself. For example, a one-to-many recursive relationship occurs when an employee is the manager of other employees. The employee entity is related to itself, and there is a one-to-many relationship between one employee (the manager) and many other employees (the people who report to the manager). Because of the more complex nature of these relationships, we will need slightly more complex methods of mapping them to a schema and displaying them in a style sheet.
The one-to-one recursive relationship
editContinuing with the tour guide model, we will develop a schema that shows cities that have hosted the Olympics and the previous host city. Since the previous host is another city and only one city can be the previous host this is a one to one recursive relationship.
host.xsd (XML schema for a one-to-one recursive model)
edit<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="cities">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="city" type="cityType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="cityType">
<xsd:sequence>
<xsd:element name="cityID" type="xsd:ID"/>
<xsd:element name="cityName" type="xsd:string"/>
<xsd:element name="cityCountry" type="xsd:string"/>
<xsd:element name="cityPop" type="xsd:integer"/>
<xsd:element name="cityHostYr" type="xsd:integer"/>
<xsd:element name="cityPreviousHost" type="xsd:IDREF" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Exhibit 1: XML schema for Host City Entity
host.xml (XML document for a one-to-one recursive model)
edit<?xml version="1.0" encoding="UTF-8"?>
<cities xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='host.xsd'>
<city>
<cityID>c1</cityID>
<cityName>Atlanta</cityName>
<cityCountry>USA</cityCountry>
<cityPop>4000000</cityPop>
<cityHostYr>1996</cityHostYr>
</city>
<city>
<cityID>c2</cityID>
<cityName>Sydney</cityName>
<cityCountry>Australia</cityCountry>
<cityPop>4000000</cityPop>
<cityHostYr>2000</cityHostYr>
<cityPreviousHost>c1</cityPreviousHost>
</city>
<city>
<cityID>c3</cityID>
<cityName>Athens</cityName>
<cityCountry>Greece</cityCountry>
<cityPop>3500000</cityPop>
<cityHostYr>2004</cityHostYr>
<cityPreviousHost>c2</cityPreviousHost>
</city>
</cities>
Exhibit 2: XML Document for Olympic Host City
The one-to-many recursive relationship
editA hypothetical sports team is divided into squads with each squad having a captain. Every person on the team is a player, regardless of whether they are a squad captain. Since a squad captain is a player, this situation meets the definition of a recursive relationship—a squad captain is also a player and has a one-to-many relationship with the other players. This is a one-to-many recursive relationship because one captain has many players under him/her. See the example below for how to model the relationship.
team.xsd (XML schema for a one-to-many recursive model)
edit<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
<xsd:element name="team">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="player" type="playerType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="playerType">
<xsd:sequence>
<xsd:element name="playerID" type="xsd:ID"/>
<xsd:element name="playerName" type="xsd:string"/>
<xsd:element name="playerCap" type="playerC" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="playerC">
<xsd:sequence>
<xsd:element name="memberOf" type="xsd:IDREF"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Exhibit 3: XML schema for Team Entity
team.xml (XML document for a one-to-many recursive model)
edit<?xml version="1.0" encoding="UTF-8"?>
<team xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='Recursive1toMSchema.xsd'>
<player>
<playerID>c1</playerID>
<playerName>Tommy Jones</playerName>
<playerCap>
<memberof>c3</memberof>
</playerCap>
</player>
<player>
<playerID>c2</playerID>
<playerName>Eddie Thomas</playerName>
<playerCap>
<memberof>c3</memberof>
</playerCap>
</player>
<player>
<playerID>c3</playerID>
<playerName>Sean McCombs</playerName>
</player>
<player>
<playerID>c4</playerID>
<playerName>Patrick O’Shea</playerName>
<playerCap>
<memberof>c3</memberof>
</playerCap>
</player>
</team>
Exhibit 4: XML Document for Team Entity
Natural one-to-many recursive structure
editA more natural approach for most one-to-many recursive relationships is to use XML's hierarchical nature to directly represent the heirarchy. Consider Locations:
<?xml version="1.0" encoding="UTF-8"?>
<location type="country">
<name>USA</name>
<sub-locations>
<location type="state">
<name>Ohio</name>
<sub-locations>
<location type="city"><name>Akron</name></location>
<location type="city"><name>Columbus</name></location>
</sub-location>
</location>
</sub-locations>
</location>
The many-to-many recursive relationship
editThink you're getting a feel for recursive relationships yet? Well, there is still the third and final relationship to add to your repertoire — the many-to-many recursive. A common example of a many-to-many recursive relationship is when one item can be comprised of many items of the same data type as itself, and each of those sub-items may belong to another parent item of the same data type. Sound confusing? Let's look at the example of a product that can consist of a single item or multiple items (i.e., a packaged product). The example below describes tourist products that can be packaged together to create a new product.
product.xsd (XML schema for a many-to-many recursive model)
edit<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
<xsd:element name="products">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="product" type="prodType" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="prodType">
<xsd:sequence>
<xsd:element name="prodID" type="xsd:ID"/>
<xsd:element name="prodName" type="xsd:string"/>
<xsd:element name="prodCost" type="xsd:decimal" minOccurs="0"/>
<xsd:element name="prodPrice" type="xsd:decimal"/>
<xsd:element name="components" type="componentsType" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="componentsType">
<xsd:sequence>
<xsd:element name="component" type="xsd:IDREF"/>
<xsd:element name="componentqty" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Exhibit 5: XML schema for Product Entity
product.xml (XML document for a many-to-many recursive model)
edit<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="product.xsl"?>
<products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="product.xsd">
<product>
<prodID>p1000</prodID>
<prodName>Animal photography kit</prodName>
<prodPrice>725</prodPrice>
<components>
<component>p101</component>
<componentqty>1</componentqty>
</components>
</product>
<product>
<prodID>p101</prodID>
<prodName>Camera case</prodName>
<prodCost>150</prodCost>
<prodPrice>300</prodPrice>
</product>
</products>
Exhibit 6: XML Document for Product Entity
Summary
editWhen the child has the same type of data as its parent in a parent-child type data relationship, this is a sign of the existence of a recursive relationship. The xsd:ID and xsd:IDREF elements can be used in a schema to create primary key-foreign key values in an XML document.
External Links