XML/Relazioni ricorsive
- Comprendere il concetto di relazione ricorsiva
- Creare uno schema per una relazione ricorsiva uno-a-uno
- Creare uno schema per una relazione ricorsiva uno-a-molti
- Creare uno schema per una relazione ricorsiva molti-a-molti
- Definire un identificatore univoco in uno schema
- Creare una relazione con chiave primaria/chiave esterna
Le relazioni ricorsive sono un concetto interessante e più complesso rispetto alle relazioni che hai visto nei capitoli precedenti. Una relazione ricorsiva si verifica quando esiste una relazione tra un'entità e se stessa. Ad esempio, una relazione ricorsiva uno-a-molti si verifica quando un dipendente è il responsabile di altri dipendenti. L'entità dipendente è correlata a se stessa e vi è una relazione uno-a-molti tra un dipendente (il manager) e molti altri dipendenti (le persone che fanno riferimento al manager). A causa della natura più complessa di queste relazioni, avremo bisogno di metodi leggermente più complessi per mapparli in uno schema e visualizzarli in un foglio di stile.
La relazione uno-a-uno ricorsiva
modificaContinuando con il modello della guida turistica, svilupperemo uno schema che mostra le città che hanno ospitato le Olimpiadi e la precedente città ospitante. Dal momento che l'host precedente è un'altra città e solo una città può essere l'host precedente questa è una relazione ricorsiva uno a uno.
host.xsd (schema XML per un modello ricorsivo uno-a-uno)
modifica<?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>
host.xml (documento XML per un modello ricorsivo uno-a-uno)
modifica<?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>Atene</cityName>
<cityCountry>Grecia</cityCountry>
<cityPop>3500000</cityPop>
<cityHostYr>2004</cityHostYr>
<cityPreviousHost>c2</cityPreviousHost>
</city>
</cities>
La relazione ricorsiva uno-a-molti
modificaUn ipotetico team sportivo è diviso in squadre, ognuna delle quali ha un capitano. Ogni persona della squadra è un giocatore, indipendentemente dal fatto che sia un capitano di squadra. Poiché un capitano di squadra è un giocatore, questa situazione incontra la definizione di una relazione ricorsiva: un capitano di squadra è anche un giocatore e ha una relazione uno-a-molti con gli altri giocatori. Si tratta di una relazione ricorsiva uno-a-molti perché un capitano ha molti giocatori sotto di sé. L'esempio seguente mostra come come modellare la relazione.
team.xsd (schema XML per un modello ricorsivo uno-a-molti)
modifica<?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>
team.xml (documento XML per un modello ricorsivo uno-a-molti)
modifica<?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>
Struttura ricorsiva naturale uno-a-molti
modificaUn approccio più naturale per la maggior parte delle relazioni ricorsive uno-a-molti è quello di utilizzare la natura gerarchica di XML per rappresentare direttamente la gerarchia. Considerare le posizioni:
<?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>
La relazione ricorsiva molti-a-molti
modificaTi senti già ferrato sulle relazioni ricorsive? Beh, c'è ancora la terza e ultima relazione da aggiungere al tuo bagaglio di conoscenze: il rapporto ricorsivo molti-a-molti. Un esempio comune di una relazione ricorsiva molti-a-molti è quando un elemento può essere composto da molti elementi dello stesso tipo di dati, e ciascuno di questi sotto-elementi può appartenere ad un altro elemento padre dello stesso tipo di dati. Sembra confuso? Vediamo l'esempio di un prodotto che può consistere di un singolo elemento o di più elementi (ad esempio, un prodotto confezionato). L'esempio che segue descrive i prodotti turistici che possono essere confezionati insieme per creare un nuovo prodotto.
product.xsd (schema XML per un modello ricorsivo molti-a-molti)
modifica<?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>
product.xml (documento XML per un modello ricorsivo molti-a-molti)
modifica<?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>Kit per la fotografia di animali</prodName>
<prodPrice>725</prodPrice>
<components>
<component>p101</component>
<componentqty>1</componentqty>
</components>
</product>
<product>
<prodID>p101</prodID>
<prodName>Custodia per fotocamera</prodName>
<prodCost>150</prodCost>
<prodPrice>300</prodPrice>
</product>
</products>