Esercitazione XML e XSD


1. Strutturare i dati in XML

In questa esercitazione vediamo come definire lo Schema XML dei messaggi scambiati da due applicazioni. Prendiamo come esempio una versione semplificata dei messaggi utilizzati nella GetCategoryInfo delle Web API di Ebay:

<GetCategoryInfoRequest xmlns="urn:ebay:apis:eBLBaseComponents">
  <CategoryID>-1</CategoryID>
  <IncludeSelector>ChildCategories</IncludeSelector>
</GetCategoryInfoRequest>

<GetCategoryInfoResponse xmlns="urn:ebay:apis:eBLBaseComponents">   
  <Timestamp>2015-03-11T12:01:49.742Z</Timestamp>   
  <Ack>Success</Ack>      
  <CategoryArray>    
    <Category>     
      <CategoryID>1234</CategoryID>     
      <CategoryLevel>1</CategoryLevel>     
      <CategoryName>Libri</CategoryName>     
      <LeafCategory>false</LeafCategory>    
    </Category>
    <Category>     
      <CategoryID>5678</CategoryID>     
      <CategoryLevel>1</CategoryLevel>     
      <CategoryName>Giochi</CategoryName>     
      <LeafCategory>true</LeafCategory>    
    </Category>
  </CategoryArray>     
</GetCategoryInfoResponse>

Obiettivo di questa esercitazione è la definizione dello Schema XML dei due messaggi e la loro validazione utilizzando Eclipse.

2. XML Schema Description

Abbiamo un esempio dei messaggi scambiati dagli attori, dobbiamo descriverne la struttura in standard XSD. Creiamo quindi un nuovo documento XML Schema.

[Suggerimento] Suggerimento

Come ambiente di sviluppo utilizzeremo la piattaforma Eclipse. Le macchine in dipartimento dovrebbero avere a disposizione una copia locale, altrimenti è disponibile un'installazione in /home/projects/isi/eclipse/eclipse.

Apriamo Eclipse e creiamo un nuovo Progetto con File -> New -> Project... -> General -> Project. Creiamo un XML Schema con File -> New -> Other -> XML -> XML Schema File.

[Suggerimento] Suggerimento

Per le macchine in dipartimento, se non sono disponibili i file di tipo XML nell'installazione personale, utilizzare l'installazione in /home/projects/isi/eclipse/eclipse. Lo stesso problema per le installazioni su macchine proprie, si risolve installando il plugin per Eclipse Web Tools Platform

Quando viene creato un nuovo XML Schema in Eclipse, troviamo le seguenti dichiarazioni:

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/esempio" 
    xmlns:tns="http://www.example.org/esempio" 
    elementFormDefault="qualified">
</schema>

Vediamone in dettaglio il significato:

  • xmlns: dichiarazione del namespace di default per questo documento. Tutti gli elementi utilizzati senza namespace si assumono appartenenti a quello di default.

  • xmlns:tns: dichiarazione del namespace http://www.example.org/esempio. Gli elementi utilizzati con il prefisso tns appartengono al quel namespace.

  • targetNamespace: il namespace che avranno gli elementi dichiarati globalmente nel documento. Sono tali se la loro dichiarazione è immediatamente figlia dell'elemento schema.

  • elementFormDefault: indica se anche gli elementi dichiarati localmente devono essere qualificati oppure no.

Il namespace utilizzato da Ebay è urn:ebay:apis:eBLBaseComponents. Modifichiamo quindi il targetNamespace ed il valore della dichiarazione del prefisso tns.

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
        elementFormDefault="qualified" 
        targetNamespace="urn:ebay:apis:eBLBaseComponents">
   
</schema>

Cominciamo con la definizione dell'elemento CategoryID. Questo elemento contiene un numero, quindi è un elemento semplice di tipo integer.

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
        elementFormDefault="qualified" 
        targetNamespace="urn:ebay:apis:eBLBaseComponents">
   
        <element name="CategoryID" type="integer"></element>

</schema>

Possiamo adesso validare un documento XML contenente il solo elemento CategoryID come verifica. Per prima cosa aggiungiamo nell'XML Catalog lo schema appena creato. Selezioniamo quindi Window -> Preferences -> XML -> XML Catalog -> Add... e aggiungiamo il nostro XSD. Creiamo quindi un nuovo documento XML con File -> New -> Other -> XML -> XML File, selezioniamo di utilizzare un XML Template come struttura di partenza e scriviamo il seguente frammento XML:

<?xml version="1.0" encoding="UTF-8"?>
<CategoryID xmlns="urn:ebay:apis:eBLBaseComponents">-1</CategoryID>

Salvato il file, validiamolo cliccando Tasto Destro > Valida. La validazione deve completarsi senza errori. Come controprova, modifichiamo il valore del CategoryID mettendo testo non numerico e validiamolo verificando che venga segnalato un errore.

Definiamo l'elemento IncludeSelector che, a differenza di CategoryID, contiene una stringa invece di un numero intero.

Definiamo adesso l'elemento radice GetCategoryInfoRequest. Questo elemento è costituito da una sequenza di due elementi CategoryID e IncludeSelector, quindi è un elemento di tipo complesso.

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
	targetNamespace="urn:ebay:apis:eBLBaseComponents"
	xmlns:tns="urn:ebay:apis:eBLBaseComponents" 
	elementFormDefault="qualified">
	<element name="GetCategoryInfoRequest">
		<complexType>
			<sequence>
				<element name="CategoryID" type="integer"></element>
				<element name="IncludeSelector" type="string"></element>
			</sequence>
		</complexType>
	</element>
</schema>
[Nota] Nota

I limiti di occorrenza dell'elemento sequence, ovvero minOccur e maxOccurs, non sono stati impostati, visto che il loro valore di default è già di 1.

Verifichiamo nuovamente il nostro lavoro validando il seguente messaggio XML:

<?xml version="1.0" encoding="UTF-8"?>
<GetCategoryInfoRequest xmlns="urn:ebay:apis:eBLBaseComponents">
	<CategoryID>-1</CategoryID>
	<IncludeSelector>ChildCategories</IncludeSelector>
</GetCategoryInfoRequest>

Abbiamo completato la scrittura dello Schema XML del messaggio di richiesta. Completiamo il primo esercizio scrivendo lo schema per il messaggio di risposta e verificare che validi il messaggio campione tenendo presente che:

  • Timestamp è un data con orario

  • CategoryLevel deve essere un intero positivo

  • LeafCategory è un booleano

  • Non ci sono limiti al numero di Category

[Suggerimento] Suggerimento

I tipi richiesti per Timestamp, CategoryLeaf e LeafCategory sono tutti tipi primitivi già presenti tra quelli XSDSchema

Soluzione

3. Esercizi di approfondimento

  1. Nella richiesta, l'elemento IncludeSelector è opzionale. Specificare l'attributo minOccurs per renderlo opzionale e verificare che una richiesta che non lo specifica sia sempre valida.

    Soluzione

  2. Nella risposta il valore dell'elemento Ack può assumere solo i valori Success e Failure. Applicare una restrizione sui i valori ammissibili e verificare che siano valide solo risposte che presentano quei valori.

    Soluzione

  3. Modificare lo schema della risposta in modo che l'elemento CategoryArray possa opzionalmente valorizzare l'attributo numCategories con il numero di categorie contenute.

    Soluzione

  4. Modificare lo schema della richiesta di modo che sia valido il seguente messaggio

    <GetCategoryInfoRequest xmlns="urn:ebay:apis:eBLBaseComponents">
      <CategoryID>-1</CategoryID>
      <IncludeSelector>ChildCategories</IncludeSelector>
      <Language xmlns="http://www.unipi.it/lai">Italian<Language>
    </GetCategoryInfoRequest>

    Sarà quindi necessario definire un nuovo file xsd per l'elemento Language, appartenendo questo ad un diverso target namespace. Per importare il nuovo XSD nello schema ebay, sarà poi possibile utilizzare l'elemento import)

Soluzione: schema elemento GetCategoryInfo

Soluzione: schema elemento Language

Footer BGFooter BG
Tito Flagella - © 2007-2015