XML - Managing Data Exchange/Recursive relationships

From Wikibooks, open books for an open world
Jump to: navigation, search



Xml book cover wiki.png XML - Managing Data Exchange
Chapters
Appendices
Exercises
Related Topics
Computer Science Home
Library and Information Science Home
Markup Languages
Get Involved
To do list
Contributors list
Contributing to Wikibooks
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




Introduction[edit]

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 relationship[edit]

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 relationship[edit]

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 structure[edit]

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 relationship[edit]

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

Summary[edit]

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.


Exercises[edit]


Answers[edit]

External Links