Tipi di dato complessi

I tipi di dato complessi fanno riferimento ad elementi in grado di contenere al loro interno eventuali altri attributi o nidificazioni. La definizione di uno di questi elementi comporta la definizione di una nuova struttura dati.

<xs:element name="elmComplex">
  <xs:complexType>
    <!-- Definizione del tipo complesso -->
  </xs:complexType>
</xs:element>
<!-- oppure -->
<xs:complexType name="myComplexType">
  <!-- Definizione del tipo complesso -->
</xs:complexType>
<xs:element name="elmComplex" type="myComplexType"/>

Se l’elemento che si vuole definire è non “vuoto” allora è possibile definire la sequenza di elementi che si possono trovare al suo interno utilizzando uno dei costruttori previsti dal linguaggio:

  1. “sequence”, consente di definire una sequenza ordinata di sotto-elementi;
  2. “choice”, consente di definire un elenco di sotto-elementi alternativi;
  3. “all”, consente di definire una sequenza non ordinata di sotto-elementi.

Vediamo ad esempio la definizione di una semplicissima anagrafica per utenti:

<xs:complexType name="userType">
  <xs:sequence>
    <xs:element name="nome" type="xs:string"/>
    <xs:element name="cognome" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

All’interno della definizione di un tipo complesso è possibile specificare il numero di occorrenze minime o massime di un certo elemento mediante l’utilizzo degli attributi minOccurs e maxOccurs, il cui valore di default è 1. La definizione di un elemento facoltativo avviene mediante la specificazione dell’attributo minOccurs con valore ‘0’.

<xs:element name="capitolo">
  <xs:complexType>
    <xs:element name="pagina" minOccurs="1" maxOccurs="unbounded"/>
  </xs:complexType>
</xs:element>

La notazione maxOccurs=”unbounded” definisce un numero illimitato di elementi, per questo motivo l’elemento “capitolo” appena definito potrà contenere uno o infiniti elementi “pagina”.

La definizione di un elemento complesso può essere eseguita ricorsivamente nei casi in cui l’elemento figlio appena definito sia a sua volta composto di un tipo complesso, tale notazione è comunque sconsigliata in favore della definizione di tipi differenti. La definizione di un elemento contenente un attributo avviene mediante l’uso del costruttore “attribute”:

<!-- elemento XML -->
<prodotto id="1345" />
<!-- definizione alternativa -->
<xs:element name="prodotto">
  <xs:complexType>
    <xs:attribute name="id" type="xs:positiveInteger"/>
  </xs:complexType>
</xs:element>
<!-- definizione alternativa -->
<xs:complexType name="prodType">
  <xs:attribute name="id" type="xs:positiveInteger"/>
</xs:complexType>
<xs:element name="prodotto" type="prodType"/>

Esempi di definizioni di tipi complessi

Mostriamo alcuni esempi di elementi XML e della loro dichiarazione in XML Schema, iniziamo analizzando un nodo XML “utente” predisposto a contenere altri nodi semplici:

<!-- elemento XML -->
<utente>
  <nome>John</nome>
  <cognome>Smith</cognome>
</utente>
<!-- definizione dell'elemento -->
<xs:element name="utente">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="nome" type="xs:string"/>
      <xs:element name="cognome" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!-- definizione alternativa -->
<xs:complexType name="userType">
  <xs:sequence>
    <xs:element name="nome" type="xs:string"/>
    <xs:element name="cognome" type="xs:string"/>
  </xs:sequence>
</xs:complexType>
<xs:element name="utente" type="userType"/>

Consideriamo un elemento “taglia” contenente un valore e un attributo:

<!-- elemento XML -->
<taglia stato="francia">35</taglia>
<!-- definizione dell'elemento -->
<xs:element name="taglia">
  <xs:complexType>
    <xs:simpleContent>
      <xs:extension base="xs:integer">
        <xs:attribute name="stato" type="xs:string" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
</xs:element>
<!-- definizione alternativa -->
<xs:complexType name="sizeType">
  <xs:simpleContent>
    <xs:extension base="xs:integer">
      <xs:attribute name="stato" type="xs:string" />
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>
<xs:element name="taglia" type="sizeType"/>

Consideriamo un elemento “lettera” predisposto a contenere degli elementi misti:

<!-- elemento XML -->
<lettera>
  Gentile Sig.<nome>John Smith</nome>.
  Il suo ordine <id_ordine>1032</id_ordine>
  sarà spedito in data <data_spedizione>13/07/2001</data_spedizione>.
</lettera>
<!-- definizione dell'elemento -->
<xs:element name="lettera">
  <xs:complexType mixed="true">
    <xs:sequence>
      <xs:element name="nome" type="xs:string"/>
      <xs:element name="id_ordine" type="xs:positiveInteger"/>
      <xs:element name="data_spedizione" type="xs:date"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!-- definizione alternativa -->
<xs:complexType name="mailType" mixed="true">
  <xs:sequence>
    <xs:element name="nome" type="xs:string"/>
    <xs:element name="id_ordine" type="xs:positiveInteger"/>
    <xs:element name="data_spedizione" type="xs:date"/>
  </xs:sequence>
</xs:complexType>
<xs:element name="lettera" type="mailType"/>