XML - 資料交換管理/遞迴關係
| 上一章 | 下一章 |
| ← 多對多關係 | 資料模式 → |
|
學習目標
|
遞迴關係是一個有趣且比你在前幾章中看到的更復雜的概念。當實體之間存在關係時,就會出現遞迴關係。例如,一對多遞迴關係發生在員工是其他員工的經理時。員工實體與其自身相關,並且一個員工(經理)與許多其他員工(向經理彙報的人)之間存在一對多關係。由於這些關係的性質更復雜,因此我們需要稍微複雜一些的方法來將它們對映到模式並以樣式表的方式顯示它們。
繼續以導遊模型為例,我們將開發一個模式,該模式顯示舉辦過奧運會的城市以及上一個舉辦城市。由於上一個舉辦城市是另一個城市,並且只有一個城市可以成為上一個舉辦城市,因此這是一對一遞迴關係。
<?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>
圖 1:舉辦城市實體的 XML 架構
<?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>
圖 2:奧運會舉辦城市的 XML 文件
假設一個運動隊分為多個小隊,每個小隊都有一名隊長。團隊中的每個人都是球員,無論他們是否是小隊隊長。由於小隊隊長也是球員,因此這種情況符合遞迴關係的定義——小隊隊長也是球員,並且與其他球員之間存在一對多關係。這是一種一對多遞迴關係,因為一名隊長手下有多名球員。請檢視下面的示例瞭解如何對這種關係進行建模。
<?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>
圖 3:團隊實體的 XML 架構
<?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>
圖 4:團隊實體的 XML 文件
對於大多數一對多遞迴關係來說,更自然的方法是使用 XML 的層次結構來直接表示層次結構。請考慮地點
<?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>
你認為你已經瞭解遞迴關係了嗎?好吧,你的技能庫中還有第三種也是最後一種關係需要新增——多對多遞迴關係。多對多遞迴關係的一個常見示例是,一個專案可以由許多與其自身資料型別相同的專案組成,並且這些子專案中的每一個可能屬於另一個與自身資料型別相同的父專案。聽起來很困惑?讓我們以一個產品為例,它可以包含單個專案或多個專案(即,包裝產品)。下面的示例描述了可以打包在一起形成新產品的旅遊產品。
<?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>
圖 5:產品實體的 XML 架構
<?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>
圖 6:產品實體的 XML 文件
當子元素在父子型別資料關係中與父元素具有相同型別的資料時,這表明存在遞迴關係。xsd:ID 和 xsd:IDREF 元素可以在模式中使用,以在 XML 文件中建立主鍵-外部索引鍵值。
外部連結
