Share |

sabato 3 aprile 2010

XSD: Utilizzare gli Undefined Types

In questo articolo sul linguaggio XSD, l'argomento che sarà affrontato riguarda la sintassi degli elementi Undefined Types (in italiano Tipi Indefiniti), come utilizzarli e perché prevederli durante la progettazione di un XSD_Schema.

L'analisi e la creazione di un'interfaccia comune per la comunicazione ed il trasporto delle informazioni durante tutte le fasi di un processo informatico di automazione aziendale è un'attività molto importante che coinvolge molti ruoli e deve soddisfare generalmente molte funzioni: capita quindi molto spesso che parte dei dati di proprio interesse rappresentino una piccola fetta delle informazioni che l'interfaccia finale dichiara di gestire!

Capita infatti di dover analizzare e trattare grandi documenti XML contenenti molti dati non direttamente utili (e necessari per altri attori del processo) ma che devono comunque esserci, perché così definiti nello Schema_XSD (l'interfaccia di cui sopra), per poter essere validati prima che un'altra procedura li utilizzi.

Per il seguente esempio di informazione XML:

<pianta>
  <nome>Geranio</nome>
  <esterno>true</esterno>
  <colore>rosso</colore>
</pianta>

definiremmo uno Schema XSD simile a questo:

<xs:element name="pianta"> 
  <xs:complexType>
    <xs:sequence>
      <xs:element name="nome" type="xs:string" />
      <xs:element name="esterno" type="xs:boolean" />
      <xs:element name="colore" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

Si valuti anche l'ipotesi verosimile che un altro sviluppatore utilizzando il nostro documento XML per la sua applicazione lo abbia esteso aggiungendo altre informazioni, per esempio il prezzo delle piante, producendo un XML definito in questa maniera:

<xs:element name="pianta">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="nome" type="xs:string" />
      <xs:element name="esterno" type="xs:boolean" />
      <xs:element name="colore" type="xs:string" />
      <xs:element name="prezzo" type="xs:float" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

Avverrebbe sicuramente che la nostra applicazione non sarebbe più in grado di
trustare ed utilizzare i documenti XML prodotti dal suddetto sviluppatore in quanto l'elemento <prezzo> non verrebbe validato con il nostro Schema XSD: in questo scenario, come nel precedente, risulta opportuno ricorrere ai tipi indefiniti:

  • xs:any per gli elementi;
  • xs:anyAttribute per gli attributi;

xs:any

Aggiungendo xs:any alla definizione XSD di un elemento, questo potrà avere qualsiasi sotto-elemento oltre a quelli già definiti.

Quindi ridefinendo l'elemento <pianta/> originale nella seguente maniera:

<xs:element name="pianta">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="nome" type="xs:string" />
      <xs:element name="esterno" type="xs:boolean" />
      <xs:element name="colore" type="xs:string" />
      <xs:any minOccurs="0" maxOccurs="unbounded"
                 processContents="skip" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

esso accetterà qualsiasi altro sotto-elemento presente nel documento XML, <prezzo /> compreso.

xs:anyAttribute

Lo stesso principio si applica agli attributi.
Altre applicazioni potrebbero utilizzare gli attributi anziché gli elementi per estendere il documento XML originale.

In questo caso, nello Schema XSD si dovrà utilizzare il tipo indefinito degli attributi xs:anyAttribute, come esposto di seguito:

<xs:element name="pianta">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="nome" type="xs:string" />
      <xs:element name="esterno" type="xs:boolean" />
      <xs:element name="colore" type="xs:string" />
      <xs:any minOccurs="0" maxOccurs="unbounded"
                 processContents="skip" />
    </xs:sequence>
    <xs:anyAttribute processContents="skip" />
  </xs:complexType>
</xs:element>

La direttiva processContent

Essa permette di definire la modalità con cui il validatore dovrà interpretare i nuovi, e sconosciuti, elementi che incontrerà processando la fonte dati XML.

Questa direttiva può assumere i seguenti valori:

  • skip: il validatore non considera i nuovi elementi;
  • lax: il validatore tenta di validare i nuovi elementi applicando lo schema corrente, nel caso non siano definiti li tralascia;
  • strict: il validatore tenta di validare i nuovi elementi applicando lo schema corrente, nel caso non siano definiti restituisce un errore;

Concludendo, sono dell'idea che per creare un'applicazione robusta e che in futuro possa essere estesa facilmente sarebbe opportuno valutare l'ipotesi di preparare interfacce applicative tramite Schemi XSD che già prevedano l'uso di elementi e di attributi indefiniti.

Facendo uno sforzo di memoria per ricordarsi di utilizzarli, ci si assicura una eventuale compatibilità con flussi di dati e documenti XML trattati anche da altre applicazioni.

Alla prossima,
MA.