XML/Relazione molti-molti
- Imparare diversi metodi per rappresentare una relazione molti-a-molti, usando XML
- Creare schemi XML utilizzando i metodi "Eliminate" e "ID/IDREF" per strutturare i contenuti sulla base di una relazione molti-a-molti.
- Creare i documenti XML corrispondenti per i metodi "Eliminate" e "ID/IDREF".
- Imparare a utilizzare la funzione chiave in un foglio di stile XML per formattare i dati strutturati con il metodo "ID/IDREF".
- Creare un foglio di stile XML di base che incorpora la funzione chiave.
Nei capitoli precedenti avete imparato a usare l'XML per strutturare e formattare i dati sulla base di relazioni uno-a-uno e uno-a-molti. Poiché XML fornisce i mezzi per modellare i dati utilizzando relazioni gerarchiche genitore-figlio, le relazioni uno-a-uno e uno-a-molti sono relativamente semplici da rappresentare in XML. Tuttavia, questa struttura gerarchica genitore-figlio è difficile da usare per modellare il rapporto molti-a-molti, un rapporto comune tra entità in molte situazioni.
In questo capitolo, esploreremo i pro e i contro di alcuni metodi usati per modellare una relazione molti-a-molti in XML; questi metodi offrono compromessi nel superare i problemi che sorgono quando si applica questa relazione a XML. In particolare, vedremo esempi di come modellare la relazione molti-a-molti utilizzando due diversi metodi, "Eliminate" e "ID/IDREF". Inoltre, nel foglio di stile XML, impareremo come implementare la funzione chiave per visualizzare i dati che sono stati modellati utilizzando il metodo "ID/IDREF".
Problemi: rapporto molti-a-molti
[modifica | modifica sorgente]In XML, la relazione genitore-figlio è più comunemente usata per rappresentare una relazione. Questo può essere facilmente applicato a un rapporto uno-a-uno o a un rapporto uno-a-molti. Una relazione molti-a-molti non è supportata direttamente da XML; la relazione genitore-figlio non funzionerà perché ogni elemento può avere un solo elemento padre. Ci sono un paio di possibili soluzioni per aggirare questo problema.
Soluzioni: rapporto molti-a-molti a molti
[modifica | modifica sorgente]Eliminate
[modifica | modifica sorgente]Crea documenti XML che eliminano la necessità di una relazione molti-a-molti.
Limitando la portata delle informazioni che vengono trasmesse, è possibile aggirare la necessità di una relazione molti-a-molti. Invece di cercare di avere un unico documento XML che comprenda tutte le informazioni, separare le informazioni dove un documento descrive solo una delle entità che partecipa al rapporto molti-a-molti. Utilizzando la nostra relazione tourGuide, ad esempio, un modo per raggiungere questo obiettivo sarebbe quello di creare un documento XML separato per ogni hotel. Il rapporto con l'attrattiva potrebbe diventare una relazione uno-a-molti. Questo metodo è più adatto a situazioni in cui l'ambito di scambio dei dati può essere limitato a sottoinsiemi di dati. Tuttavia, utilizzando questo metodo per uno scambio di dati più ampio, è possibile ripetere i dati più volte, specialmente se ci sono molti attributi. Per evitare questa ridondanza, utilizzare il metodo ID/IDREF.
ID/IDREF
[modifica | modifica sorgente]Rappresentare il rapporto molti-a-molti a molti utilizzando identificatori unici.
Anche se non è il modo più facile per gestire questo problema, un modo per aggirare il rapporto molti-a-molti è quello di creare chiavi che identificano in modo univoco ogni entità. Per fare questo, un elemento con attributi-tipo ID o IDREF deve essere specificato all'interno dello schema XML. Per utilizzare un'analogia, ID è simile alla chiave primaria e IDREF è simile alla chiave esterna.
Modello di dati di relazione molti-a-molti
[modifica | modifica sorgente]Viene data la relazione: "un hotel può avere molti servizi, e un'attrattiva può esistere in molti alberghi".
Come noterete, per rappresentare una relazione molti-a-molti, sono state aggiunte due entità. L'entità centrale è necessaria perché il modello di dati rappresenti un'entità associativa che memorizza i dati sul rapporto tra hotel e servizi. Utilizzando l'esempio della nostra guida turistica, "Amenity" è stato aggiunto per rappresentare una lista di possibili servizi che un hotel può avere.
Gli esempi che seguono illustrano i metodi per rappresentare una relazione molti-a-molti in XML.
Eliminare: soluzione campione
[modifica | modifica sorgente]In questo esempio, il rapporto molti-a-molti è stato convertito in un rapporto uno a molti.
Schema XML
[modifica | modifica sorgente]Esempio 2: schema XML per il metodo "Eliminate".
<?xml version="1.0" encoding="UTF-8"?
<!--
Documento : amenity1.xsd
Creato il : 4 febbraio 2006
Autore : Il dottor Rick Watson.
-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
<xsd:element name="hotelGuide">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="hotel" type="hotelDetails" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="emailAddressType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\w+\W*\w*@{1}\w+\W*\w+.\w+.*\w*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="hotelDetails">
<xsd:sequence>
<xsd:element name="hotelPicture"/>
<xsd:element name="hotelName" type="xsd:string"/>
<xsd:element name="streetAddress" type="xsd:string"/>
<xsd:element name="postalCode" type="xsd:string" minOccurs="0"/>
<xsd:element name="telephoneNumber" type="xsd:string"/>
<xsd:element name="emailAddress" type="emailAddressType" minOccurs="0"/>
<xsd:element name="websiteURL" type="xsd:anyURI" minOccurs="0"/>
<xsd:element name="hotelRating" type="xsd:integer" default="0"/>
<xsd:element name="lowerPrice" type="xsd:positiveInteger"/>
<xsd:element name="upperPrice" type="xsd:positiveInteger"/>
<xsd:element name="amenity" type="amenityValue" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="amenityValue">
<xsd:sequence>
<xsd:element name="amenityType" type="xsd:string"/>
<xsd:element name="amenityOpenHour" type="xsd:time"/>
<xsd:element name="amenityCloseHour" type="xsd:time"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Documento XML
[modifica | modifica sorgente]Esempio 3: documento XML per il metodo "Eliminate".
<?xml version="1.0" encoding="UTF-8"?>
<!--
Documento : amenity1.xml
Creato il : 4 febbraio 2006
Autore : Il dottor Rick Watson.
-->
<hotelGuide xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="amenity1.xsd">
<hotel>
<hotelPicture/>
<hotelName>Narembeen Hotel</hotelName>
<streetAddress>Churchill Street</streetAddress>
<telephoneNumber>+61 (08) 9064 7272</telephoneNumber>
<emailAddress>[email protected]</emailAddress>
<hotelRating>1</hotelRating>
<lowerPrice>50</lowerPrice>
<upperPrice>100</upperPrice>
<amenity>
<amenityType>Ristorante</amenityType>
<amenityOpenHour>06:00:00</amenityOpenHour>
<amenityCloseHour>22:00:00 </amenityCloseHour>
</amenity>
<amenity>
<amenityType>Piscina</amenityType>
<amenityOpenHour>06:00:00</amenityOpenHour>
<amenityCloseHour>18:00:00 </amenityCloseHour>
</amenity>
<amenity>
<amenityType>Colazione gratuita</amenityType>
<amenityOpenHour>07:00:00</amenityOpenHour>
<amenityCloseHour>10:00:00 </amenityCloseHour>
</amenity>
</hotel>
<hotel>
<hotelPicture/>
<hotelName>Narembeen Caravan Park</hotelName>
<streetAddress>Currall Street</streetAddress>
<telephoneNumber>+61 (08) 9064 7308</telephoneNumber>
<emailAddress>[email protected]</emailAddress>
<hotelRating>1</hotelRating>
<lowerPrice>20</lowerPrice>
<upperPrice>30</upperPrice>
<amenity>
<amenityType>Piscina</amenityType>
<amenityOpenHour>10:00:00</amenityOpenHour>
<amenityCloseHour>22:00:00 </amenityCloseHour>
</amenity>
</hotel>
</hotelGuide>
ID/IDREF: esempio di soluzione
[modifica | modifica sorgente]Per evitare ridondanza, creiamo un elemento separato, "amenity", che è incluso nella parte superiore dello schema insieme a "hotel". Ricordate che i tipi di dati ID e IDREF sono sinonimi rispettivamente di chiave primaria e chiave esterna. Per ogni chiave esterna (IDREF), deve esserci una chiave primaria (ID) corrispondente. Si noti che il tipo di dati IDREF deve essere una stringa alfanumerica.
L'esempio seguente illustra l'approccio ID/IDREF. Si noti che l'ID per il servizio della piscina è definito come "k1", e ogni hotel con una piscina ha come riferimento ai servizi "k1", utilizzando IDREF. Se l'IDREF non corrisponde ad alcun ID, il documento non verrà convalidato.
Schema XML
[modifica | modifica sorgente]Esempio 4: Schema XML per il metodo "ID/IDREF".
<?xml version="1.0" encoding="UTF-8"?
<!--
Documento : amenity2.xsd
Creato il : 4 febbraio 2006
Autore : Il dottor Rick Watson.
-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
<xsd:element name="hotelGuide">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="hotel" type="hotelDetails" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element name="amenity" type="amenityList" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="emailAddressType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\w+\W*\w*@{1}\w+\W*\w+.\w+.*\w*"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="hotelDetails">
<xsd:sequence>
<xsd:element name="hotelPicture"/>
<xsd:element name="hotelName" type="xsd:string"/>
<xsd:element name="streetAddress" type="xsd:string"/>
<xsd:element name="postalCode" type="xsd:string" minOccurs="0"/>
<xsd:element name="telephoneNumber" type="xsd:string"/>
<xsd:element name="emailAddress" type="emailAddressType" minOccurs="0"/>
<xsd:element name="websiteURL" type="xsd:anyURI" minOccurs="0"/>
<xsd:element name="hotelRating" type="xsd:integer" default="0"/>
<xsd:element name="lowerPrice" type="xsd:positiveInteger"/>
<xsd:element name="upperPrice" type="xsd:positiveInteger"/>
<xsd:element name="amenities" type="amenityDesc" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="amenityDesc">
<xsd:sequence>
<xsd:element name="amenityIDREF" type="xsd:IDREF"/>
<xsd:element name="amenityOpenHour" type="xsd:time"/>
<xsd:element name="amenityCloseHour" type="xsd:time"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="amenityList">
<xsd:sequence>
<xsd:element name="amenityID" type="xsd:ID"/>
<xsd:element name="amenityType" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Documento XML
[modifica | modifica sorgente]Esempio 5: documento XML per il metodo "ID/IDREF".
<?xml-stylesheet href="amenity2.xsl" type="text/xsl" media="screen"?>
<hotelGuide xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="amenity2.xsd">
<hotel>
<hotelPicture/>
<hotelName>Narembeen Hotel</hotelName>
<streetAddress>Churchill Street</streetAddress>
<telephoneNumber>+61 (08) 9064 7272</telephoneNumber>
<emailAddress>[email protected]</emailAddress>
<hotelRating>1</hotelRating>
<lowerPrice>50</lowerPrice>
<upperPrice>100</upperPrice>
<amenities>
<amenityIDREF>k2</amenityIDREF>
<amenityOpenHour>06:00:00</amenityOpenHour>
<amenityCloseHour>22:00:00 </amenityCloseHour>
</amenities>
<amenities>
<amenityIDREF>k1</amenityIDREF>
<amenityOpenHour>06:00:00</amenityOpenHour>
<amenityCloseHour>18:00:00 </amenityCloseHour>
</amenities>
<amenities>
<amenityIDREF>k5</amenityIDREF>
<amenityOpenHour>07:00:00</amenityOpenHour>
<amenityCloseHour>10:00:00 </amenityCloseHour>
</amenities>
</hotel>
<hotel>
<hotelPicture/>
<hotelName>Narembeen Caravan Park</hotelName>
<streetAddress>Currall Street</streetAddress>
<telephoneNumber>+61 (08) 9064 7308</telephoneNumber>
<emailAddress>[email protected]</emailAddress>
<hotelRating>1</hotelRating>
<lowerPrice>20</lowerPrice>
<upperPrice>30</upperPrice>
<amenities>
<amenityIDREF>k1</amenityIDREF>
<amenityOpenHour>10:00:00</amenityOpenHour>
<amenityCloseHour>22:00:00 </amenityCloseHour>
</amenities>
</hotel>
<amenity>
<amenityID>k1</amenityID>
<amenityType>Piscina</amenityType>
</amenity>
<amenity>
<amenityID>k2</amenityID>
<amenityType>Ristorante</amenityType>
</amenity>
<amenity>
<amenityID>k3</amenityID>
<amenityType>Sala fitness</amenityType>
</amenity>
<amenity>
<amenityID>k4</amenityID>
<amenityType>Colazione gratuita</amenityType>
</amenity>
<amenity>
<amenityID>k5</amenityID>
<amenityType>in-room data port</amenityType>
</amenity>
<amenity>
<amenityID>k6</amenityID>
<amenityType>Scivolo d'acqua</amenityType>
</amenity>
</hotelGuide>
Funzione chiave: foglio di stile XML
[modifica | modifica sorgente]Per impostare un foglio di stile XML utilizzando il metodo ID/IDREF per una relazione molti-a-molti, si dovrebbe usare la funzione chiave. Nel foglio di stile, l'elemento <xsl:key> specifica l'indice, che viene utilizzato per restituire un node-set dal documento XML.
Una chiave è costituita da quanto segue:
- il nodo che ha la chiave,
- il nome della chiave,
- il valore di una chiave
Il seguente foglio di stile XML illustra come utilizzare la funzione chiave per presentare contenuti strutturati in una relazione molti-a-molti.
Foglio di stile XML
[modifica | modifica sorgente]Esempio 6: Foglio di stile XML per il metodo "ID/IDREF".
<?xml version="1.0" encoding="UTF-8"?>
<!--
Documento : amenity2.xsl
Creato il : 4 febbraio 2006
Autore : Il dottor Rick Watson.
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="amList" match="amenity" use="amenityID"/>
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>Hotel Guide</title>
</head>
<body>
<h2>Hotels</h2>
<xsl:apply-templates select="hotelGuide"/>
</body>
</html>
</xsl:template>
<xsl:template match="hotelGuide">
<xsl:for-each select="hotel">
<xsl:value-of select="hotelName"/>
<br/>
<xsl:for-each select="amenities">
<xsl:value-of select="key('amList',amenityIDREF)/amenityType"/>
<xsl:text> </xsl:text>
<xsl:value-of select="amenityOpenHour"/> -
<xsl:value-of select="amenityCloseHour"/>
<BR/>
</xsl:for-each>
<br/>
<br/>
</xsl:for-each>
<br/>
</xsl:template>
</xsl:stylesheet>
Riferimenti
[modifica | modifica sorgente]