XML - Managing Data Exchange/Recursive relationships



Previous Chapter Next Chapter
The many-to-many relationship Data schemas



Learning objectives

  • Understand the concept of a recursive relationship
  • Create a schema for a one-to-one recursive relationship
  • Create a schema for a one-to-many recursive relationship
  • Create a schema for a many-to-many recursive relationship
  • Define a unique identifier in a schema
  • Create a primary key/foreign key relationship




IntroductionEdit

Recursive 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 relationshipEdit

Continuing 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.

Recursive


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 relationshipEdit

A 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 structureEdit

A more natural approach for most one-to-many recursive relationships is to use XML's heirarchical 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 relationshipEdit

Think 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

SummaryEdit

When 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.


ExercisesEdit


AnswersEdit

External Links

Last modified on 2 September 2012, at 19:20