Massimo Martinelli
massimo AT w3c [DOT it
Ufficio Italiano W3C, CNR-ISTI
Area della Ricerca CNR
via Moruzzi, 1
56124 Pisa
Corso AQUARIUS sulle Tecnologie Web
Firenze 19 Ottobre 2010 - Pisa, 26 Ottobre 2010
da Ivan Herman
150,25 179,111 625,30 580,90 640,130 197,165 223,251 150,200 77,251 103,165 31,111 121,111
Tre parti fondamentali distinte:
Anagrafe.xml
<?xml version="1.0" encoding="utf-8" ?>
<anagrafe>
<cie numerocarta="XX123456YY">
<cognome>Rossi</cognome>
<nome>Mario</nome>
<datanascita>
<giorno>20</giorno>
<mese>03</mese>
<anno>2003</anno>
</datanascita>
<luogonascita>
<comune>Livorno</comune>
<provincia>LI</provincia>
</luogonascita>
</cie>
</anagrafe>
Un ipotetico colloquio tra un Ente
(es. Ministero degli Interni, Prefettura,
Camera di Commercio, ...)
e l'Anagrafe
Uno degli obiettivi di progettazione di XML
è che sia in un formato leggibile dall'uomo,
per intendersi non può essere in formato binario,
e dovrebbe essere ragionevolmente chiaro.
Ogni documento XML inizia con un prologo
contiene una dichiarazione di versione
l'insieme di caratteri utilizzato (character set)
<?xml version="1.0" encoding="utf-8" ?>
. . .
Documento conforme alla versione 1.0 di XML
Documento che usa caratteri appartenenti alla codifica UTF-8
Radice (root): elemento che racchiude tutti gli altri
<?xml version="1.0" encoding="utf-8"?>
<anagrafe>
. . .
</anagrafe>
Ogni tag di apertura deve avere un corrispondente tag di chiusura </nome_elemento>
Forma concisa per elementi senza contenuto:
<nome_elemento />
forme equivalenti
<nome_elemento attr="valore"></nome_elemento>
<nome_elemento attr="valore" />
Esempi HTML
<br /> (<br></br> )
<img src="http://www.w3.org/Icons/w3c_home" alt="W3C" />
I tag devono essere nidificati correttamente
<aa>
<bb>
</aa>
</bb>
<aa>
<bb>
</bb>
</aa>
XML è case sensitive
le lettere maiuscole e quelle minuscole sono interpretate differentemente
<nome> != <Nome> != <NOME>
i tag XML per convenzione si scrivono in minuscolo (previsto nella prima recommendation)
Alcuni caratteri e sequenze di caratteri sono riservati, pertanto non si possono utilizzare nei nomi di tag (%, xml, ...).
<cie numerocarta="XX123456YY">
Sintassi:
<elemento attributo="valore">contenuto</elemento>
Quotare gli attributi
<!ELEMENT anagrafe (cie+)>
<!ELEMENT cie (cognome, nome, datanascita, luogonascita, luogoresidenza?, infoaggiuntiva*)>
<!ATTLIST cie
numerocarta ID #REQUIRED>
<!ELEMENT cognome (#PCDATA)>
<!ELEMENT nome (#PCDATA)>
<!ELEMENT datanascita (giorno, mese, anno)>
<!ELEMENT giorno (#PCDATA)>
<!ELEMENT mese (#PCDATA)>
<!ELEMENT anno (#PCDATA)>
<!ELEMENT luogonascita (comune, provincia, statoestero?)>
<!ELEMENT comune (#PCDATA)>
<!ELEMENT provincia (#PCDATA)>
<!ELEMENT statoestero (#PCDATA)> <!-- solo se != Italia -->
<!ELEMENT luogoresidenza (comune, provincia, statoestero?)> <!-- solo se diversa da quella di nascita -->
<!ELEMENT infoaggiuntiva (#PCDATA)>
Un documento XML si dice "ben formato" quando:
Un documento si dice "valido" quando
Analizzano i documenti XML, due tipi:
Utili entrambi, utilizzo in contesti differenti
(a volte non serve verificare la validità ma solo la correttezza)
<!ELEMENT nome (#PCDATA)>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
. . . dichiarazioni di elementi . . .
</schema>
xmlns:prefisso="URIunivoco"
A cosa ci possono servire gli spazi di nomi ?
<html:body xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xhtml:h1>text</xhtml:h1>
</html:body>
body e h1 appartengono al namespace HTML
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:dc="http://purl.org/metadata/dublin-core"
...
<xhtml:p>questo è un paragrafo xhtml</xhtml:p>
<dc:Creator>Mario Rossi</dc:Creator>
<?xml version="1.0" encoding="utf-8"?>
<anagrafe xmlns="http://www.comune.livorno.it"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.comune.livorno.it
anagrafe.xsd">
<cie numerocarta="XX123456YY">
<cognome>Rossi</cognome>
<nome>Mario</nome>
<datanascita>
<giorno>20</giorno>
<mese>03</mese>
<anno>2003</anno>
</datanascita>
<luogonascita>
<comune>Livorno</comune>
<provincia>LI</provincia>
</luogonascita>
</cie>
</anagrafe>
(supponendo che xsd identifichi il namespace XMLSchema)
definizione di un elemento titolo di tipo string
<xsd:element name="titolo" type="string" />
Sintassi:
<xsd:element name="nome_elemento" type="tipo_elemento" />
Tipi semplici predefiniti in XML Schema | ||||
---|---|---|---|---|
Tipo Semplice | Esempi (delimitati da virgola) | |||
string | Testo di esempio | |||
normalizedString | Testo di esempio | |||
token | Testo di esempio | |||
base64Binary | GpM7 | |||
hexBinary | 0FB7 | |||
integer | ...-1, 0, 1, ... | |||
positiveInteger | 1, 2, ... | |||
negativeInteger | ... -2, -1 | |||
nonNegativeInteger | 0, 1, 2, ... | |||
nonPositiveInteger | ... -2, -1, 0 | |||
long | -9223372036854775808, ... -1, 0, 1, ... 9223372036854775807 | |||
unsignedLong | 0, 1, ... 18446744073709551615 | |||
int | -2147483648, ... -1, 0, 1, ... 2147483647 | |||
unsignedInt | 0, 1, ...4294967295 | |||
short | -32768, ... -1, 0, 1, ... 32767 | |||
unsignedShort | 0, 1, ... 65535 | |||
byte | -128, ...-1, 0, 1, ... 127 | |||
unsignedByte | 0, 1, ... 255 | |||
decimal | -1.23, 0, 123.4, 1000.00 | |||
float | -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN | |||
double | -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN | |||
boolean | true, false, 1, 0 | |||
duration | P1Y2M3DT10H30M12.3S | |||
dateTime | 1999-05-31T13:20:00.000-05:00 | |||
date | 1999-05-31 | |||
time | 13:20:00.000, 13:20:00.000-05:00 | |||
gYear | 1999 | |||
gYearMonth | 1999-02 | |||
gMonth | --05 | |||
gMonthDay | --05-31 | |||
gDay | ---31 | |||
Name | shipTo | |||
QName | po:USAddress | |||
NCName | USAddress | |||
anyURI |
| |||
language | it, en-GB, en-US, fr | |||
ID | ||||
IDREF | ||||
IDREFS | ||||
ENTITY | ||||
ENTITIES | ||||
NOTATION | ||||
NMTOKEN |
| |||
NMTOKENS |
|
<xsd:complexType name="libro">
<xsd:sequence>
<xsd:element name="titolo" type="xsd:string"/>
<xsd:element name="autore" type="xsd:string"/>
<xsd:element name="editore" type="xsd:string"/>
<xsd:element name="pagine" type="xsd:positiveinteger"/>
</xsd:sequence>
<xsd:attribute name="isbn" type="xsd:string"/>
</xsd:complexType>
sequence: sequenza di elementi con ordine prefissato
equivale alla "," (virgola) del DTD
<xsd:complexType name="libro">
<xsd:sequence>
<xsd:element name="titolo" type="xsd:string"/>
<xsd:element name="autore" type="xsd:string" maxOccurs="unbounded" />
<xsd:element name="editore" type="xsd:string"/>
<xsd:element name="pagine" type="xsd:positiveinteger"/>
</xsd:sequence>
<xsd:attribute name="isbn" type="xsd:string"/>
</xsd:complexType>
È possibile assegnare agli elementi di tipo semplice un valore per difetto
<xs:element name="colore" type="xs:string" default="rosso" />
È possibile specificare un valore prefissato (fixed) (non è possibile specificare un altro valore)
<xs:element name="colore" type="xs:string" fixed="rosso" />
Gli attributi sono sempre di tipo semplice (predefinito o derivato per restrizione)
Tutti gli attributi sono opzionali per difetto
Per specificare esplicitamente che un attributo è opzionale è necessario specificare l'attributo "use".
<xs:attribute name="lang" type="xs:string" use="optional" />
Per rendere un attributo obbligatorio:
<xs:attribute name="lang" type="xs:string" use="required" />
Per proibire l'uso di un attributo
<xs:attribute name="lang" use="prohibited" />
Gli attributi possono occorrere una sola volta
È possibile assegnare agli attributi un valore per difetto
<xs:attribute name="lang" type="xs:string" default="IT" />
È possibile specificare un valore prefissato (fixed) (non è possibile specificare un altro valore)
<xs:attribute name="lang" type="xs:string" fixed="IT" />
<xsd:simpleType name="percentuale">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0" />
<xsd:maxInclusive value="100" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="CodiceType">
<xsd:restriction base="xsd:ID">
<xsd:pattern value="[a-zA-Z]{1}-\d{3}"/>
</xsd:restriction>
</xsd:simpleType>
SIMBOLO | Valori possibili |
---|---|
\d | numero decimale |
\s\w | uno spazio seguito da un carattere (word) |
ñ | ? |
\p{Lu} | carattere maiuscolo |
\p{IsGreek} | carattere dell'alfabeto Greco |
\P{IsGreek} | carattere non dell'alfabeto Greco |
a*x | *=0,1,n volte --> x, ax, aax, aaax, ... |
a?x | ? = 0, 1 volte --> x, ax |
a+x | +=1,n volte --> ax, aax, aaax, ... |
(a|b)+x | a oppure b, seguito da x --> ax, bx, aax, bbx, abx, ... |
[abcde]x | [ ] uno dei simboli presenti all'interno ax, bx, cx, dx, ex |
[a-e] | uno dei simboli tra "a" ed "e" (minuscolo) a, b,c, d, e |
[-ae]x | -x, ax, ex |
[^0-9]x | qualsiasi carattere non compreso tra 0 e 9 seguito da x |
\D | qualsiasi carattere non cifra numerica seguito da x |
.x | qualsiasi carattere seguito da x |
.*abc.* | qualsiasi sequenza di caratteri seguita da abc seguita da qualsiasi sequenza di caratteri |
ab{2}x | abbx (2 volte il carattere b) |
ab{2,4}x | da 2 a 4 volte il carattere b --> abbx, abbbx, abbbbx |
ab{2,}x | almeno 2 caratteri b --> abbx, abbbx, abbbx, ... |
length | lunghezza fissa |
minLength | lunghezza minima |
maxLength | lunghezza massima |
pattern | modello (espressione regolare) |
enumeration | enumerazione |
whiteSpace | spazio |
minExclusive | valore minimo (non incluso) |
maxExclusive | valore massimo (non incluso) |
minInclusive | valore minimo (incluso) |
maxInclusive | valore massimo (incluso) |
totalDigits | numero totale di cifre |
fractionDigits | numero cifre dopo la virgola per un decimale, frazione di secondo,...) |
applicabili sulla base del tipo (numerico, stringa, binario)
Appendice B della raccomandazione: "Simple Types & their Facets"
<xsd:simpleType name="LinguaType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Italiana"/>
<xsd:enumeration value="Francese"/>
<xsd:enumeration value="Inglese"/>
</xsd:restriction>
</xsd:simpleType>
È possibile definire insiemi di tipi nominati e dichiarare elementi che li riferiscono
È possibile definire un nuovo tipo anonimamente all'interno della definizione di un elemento (comodo nel caso il nuovo tipo venga usato solo una volta)
<xsd:complexType name="Oggetti"> <!-- Tipo nominato -->
<xsd:sequence>
<xsd:element name="oggetto" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType> <!-- Tipo anonimo -->
<xsd:sequence>
<xsd:element name="nomeProdotto" type="xsd:string"/>
<xsd:element name="quantita">
<xsd:simpleType> <!-- Tipo anonimo -->
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxExclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="prezzo" type="xsd:decimal"/>
<xsd:element name="dataAcquisto" type="xsd:date" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
Normalmente i dati in forma di carattere (PCDATA) sono ammessi all'interno degli elementi
XML Schema fornisce un metodo per permettere che tali dati possano essere esterni ai sotto-elementi
<lettera>
<saluto>Caro Sig. </saluto><nome>Mario Rossi</nome>
Il giorno <dataSpedizione>200-03-21</dataSpedizione>
abbiamo provveduto a spedirle n. <quantitativo>1</quantitativo>
<nomeProdotto>computer</nomeProdotto>
Cordiali saluti
</lettera>
Schema XML relativo
<xsd:element name="lettera">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="saluto" type="xsd:string">
<xsd:element name="nome" type="xsd:string" />
<xsd:element name="dataSpedizione" type="xsd:date" />
<xsd:element name="quantitativo" type="xsd:positiveInteger"/>
<xsd:element name="nomeProdotto" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Oltre al modello sequence esiste un altro modello per per vincolare gli elementi: choice. In un gruppo gli elementi possono apparire in modo mutuamente esclusivo (or)
<xsd:complexType name="primoOsecondoType">
<xsd:choice>
<xsd:element name="primo" type="xsd:string" />
<xsd:element name="secondo" type="xsd:string" />
</xsd:choice>
</xsd:complexType>
Scrivere uno Schema XML che rappresenti una classe di documenti "residenza" con queste caratteristiche:
Per ogni persona indicare la nuova residenza (via, numero civico, cap, comune, data cambio di residenza)
e ogni eventuale precedente residenza
Scrivere una istanza XML conforme allo Schema XML definito
Validare il documento (Validatore)
<!ELEMENT anagrafe (cie+)>
<!ELEMENT cie (cognome, nome, datanascita, luogonascita, luogoresidenza?, infoaggiuntiva*)>
<!ATTLIST cie
numerocarta ID #REQUIRED>
<!ELEMENT cognome (#PCDATA)>
<!ELEMENT nome (#PCDATA)>
<!ELEMENT datanascita (giorno, mese, anno)>
<!ELEMENT giorno (#PCDATA)>
<!ELEMENT mese (#PCDATA)>
<!ELEMENT anno (#PCDATA)>
<!ELEMENT luogonascita (comune, provincia, statoestero?)>
<!ELEMENT comune (#PCDATA)>
<!ELEMENT provincia (#PCDATA)>
<!ELEMENT statoestero (#PCDATA)> <!-- solo se != Italia -->
<!ELEMENT luogoresidenza (comune, provincia, statoestero?)> <!-- solo se diversa da quella di nascita -->
<!ELEMENT infoaggiuntiva (#PCDATA)>
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="anagrafe">
<xs:complexType>
<xs:sequence>
<xs:element name="cie" type="cieType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="cieType">
<xs:sequence>
<xs:element ref="cognome"/>
<xs:element ref="nome"/>
<xs:element name="datanascita" type="datanascitaType"/>
<xs:element name="luogonascita" type="luogonascitaType"/>
<xs:element name="luogoresidenza" type="luogoresidenzaType" minOccurs="0"/>
<xs:element ref="infoaggiuntiva" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="numerocarta" type="xs:ID" use="required"/>
</xs:complexType>
<xs:element name="cognome" type="xs:string"/>
<xs:element name="nome" type="xs:string"/>
<xs:complexType name="datanascitaType">
<xs:sequence>
<xs:element ref="giorno"/>
<xs:element ref="mese"/>
<xs:element ref="anno"/>
</xs:sequence>
</xs:complexType>
<xs:element name="giorno" type="xs:gDay"/>
<xs:element name="mese" type="xs:gMonth"/>
<xs:element name="anno" type="xs:gYear"/>
<xs:element name="infoaggiuntiva" type="xs:string"/>
<xs:complexType name="luogonascitaType">
<xs:sequence>
<xs:element ref="comune"/>
<xs:element ref="provincia"/>
<xs:element ref="statoestero" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="luogoresidenzaType">
<xs:sequence>
<xs:element ref="comune"/>
<xs:element ref="provincia"/>
<xs:element ref="statoestero" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:element name="comune" type="xs:string"/>
<xs:element name="provincia" type="xs:string"/>
<xs:element name="statoestero" type="xs:string"/>
</xs:schema>
Domande?
Se non è sul Web non esiste ...
... troverete le slide all'indirizzo (http://www1.isti.cnr.it/~Martinelli/XML/doc/Corsi_Regione2010/)