eXtensible Markup Language
Schemas
Interrogation
APIs
DTD
XML Schema
RelaxNG
Désignation de parties de documents:
XPath
Transformation de documents
XSLT
Bases de données dédiées XML
XQuery
DOM: Document Object Model
parcours, modification
SAX, StAX (Java)
parsing, traitement en flux
\(\neq\) type de noeuds:
racine (document)
possède exactement 1 enfant de type élément
cet élément va contenir les données
élément
attribut
texte
commentaire
commandes (processing instructions)
A base de balises, comme HTML
Prologue (optionnel): infos pour la lecture du document
<?xml version="1.0" encoding="utf-8"?>
Déclaration de DTD (optionnel): forme du document
<!DOCTYPE element-principal spec-DTD[ ... déclarations ...]>
Eléments et attributs:
<nom att1="val1" att2='val2'> Enfants </nom>
ou
<nom att1="val1" att2='val2'/>
L'ordre entre les enfants (éléments, texte) est significatif
L'ordre entre les attributs n'est pas significatif
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE collection SYSTEM "collecbd.dtd"> <collection> <serie nom="Lanfeust de Troy"> <tome numero="1"> <scenariste>Arleston</scenariste> <dessinateur>Tarquin</dessinateur> <titre>L'ivoire du Magohamoth</titre> </tome> <tome numero="2"> <dessinateur>Tarquin</dessinateur> <titre>Thanos l'incongru</titre> </tome> <editeur nom="Soleil"/> </serie> </collection>
([A-Z]|"\_"|[a-z]|...)([A-Z]|"\_"|[a-z]|"-"|"."|[0-9]|...)*
nomLocal
prefixe:nomLocal
prefixe
xmlns
xmlns:pref
pref
<?xml version="1.0" encoding="utf-8"?> <livres xmlns="http://www.livres-pas-chers.com"> <livre xmlns:encyclo="http://toutsurleslivres.org" ISBN="123456"> <auteur encyclo:nat="Américain">Stephen King</auteur> <titre>Le fléau</titre> <annee>2003</annee> <encyclo:annee>1978</encyclo:annee> <prix>5.3</prix> </livre> </livres>
Espaces de nommage: http://www.livres-pas-chers.com http://toutsurleslivres.org aucun.
\(\Rightarrow\) DTD, XML Schema
<!ELEMENT
nom
contenu
>
contenu
peut être:
EMPTY
: pas d'enfant
ANY
: contenu arbitraire
(#PCDATA|nom_1|nom_2|...)
: mélange de texte
d'éléments
(
expr
)
: expression rationnelle de nom d'éléments
expr | ::= | expr1, expr2 |
expr * |
||
expr ? |
||
expr + |
||
expr1 | expr2 | ||
nom | ||
(expr) |
<!ATTLIST
nom
dec1
dec2
>
dec
peut être:
type
peut être:
CDATA
, ID
, IDREF
ou IDREFS
val1
| val2
| …)
<!ELEMENT collection (serie*)> <!ELEMENT serie (tome+,editeur?)> <!ATTLIST serie nom CDATA #REQUIRED> <!ELEMENT tome (scenariste?,dessinateur?,titre)> <!ATTLIST tome numero CDATA #REQUIRED> <!ELEMENT scenariste (#PCDATA)> <!ELEMENT dessinateur (#PCDATA)> <!ELEMENT titre (#PCDATA)> <!ELEMENT editeur EMPTY> <!ATTLIST editeur nom CDATA #REQUIRED adresse CDATA #IMPLIED>
"Aller sur un élément tome
, puis sur un élément dessinateur
"
Evaluer à partir du 1er élément serie
Types de valeur possible:
/
/
en début d'expression: départ forcé depuis la racine (document)
axe::test[predicat]
[predicat]
est optionnel
forward | backward |
---|---|
child | parent |
descendant | ancestor |
attribute | |
self | |
descendant-or-self | ancestor-or-self |
following-sibling | preceding-sibling |
following | preceding |
Tests
element() | element(nom) |
attribute() | attribute(nom) |
* | nom |
text() | |
comment() | |
processing-instruction() | |
node() |
Prédicats: expressions booléennes
Expressions classiques:
and
, or
, not(...)
Plus des conversions implicites
child::un-test
↔ un-test
attribute::un-test
↔ @un-test
xxx/descendant-or-self::node()/yyy
↔ xxx//yyy
parent::node()/xxx
↔ ../xxx
axe::test[pr_1 and pr_2]
↔ axe::test[pr_1][pr_2]
Fonction pos()
Entier \(n\) \(\rightarrow\) booléen
pos() = n
serie/tome[3] child::element(serie)/child::element(tome)[pos() = 3]
"Le troisième enfant tome
pour chaque enfant serie
"
Rappel
expression + point de départ \(\rightarrow\) ensemble de noeuds
Test
\(\rightarrow \quad \neq \emptyset\) ?
serie/tome[dessinateur] child::element(serie)/child::element(tome)[child::dessinateur]
"Les enfants tome
contenant un enfant dessinateur
pour chaque
enfant serie
"
Généralisation de la construction précédente
Intuitivement
"Existe-il pour chaque chemin un noeud qui rende l'expression vraie ?"
serie[tome/@numero >= 3] child::element(serie)[child::element(tome)/attribute::attribute(numero) >= 3]
"Les enfants serie
tels qu'il existe un attribut numero
dans un
enfant tome
de cette serie
dont la valeur est supérieure ou égale
à 3"
Fonction \(eval(noeud~n, chemin~c)\)
\(\rightarrow\) ensemble des noeuds accessibles
en suivant \(c\) à partir de \(n\)
Remplacer chaque chemin \(c_i\) dans l'expression \(e\) par une variable \(x_i\) \(\rightarrow\) on obtient \(e'\)
Ajouter \(\exists x_i, x_i \in eval(n,c_i)\) devant \(e'\) pour chaque \(c_i\)
[tome/dessinateur = /tome/scenariste]
devient
\(\exists x_1, x_1 \in eval(n,\) tome/dessinateur
\(),\)
\(\exists x_2, x_2\in eval(n,\) tome/scenariste
\(),\)
\(x_1 = x_2\)
Revoir la DTD collection.
Donner une expression XPath pour obtenir:
axe::test
peut être remplacée
par une expression entre parenthèses
/collection/(serie/tome)[3]
Fonctions prenant et ou renvoyant des ensembles de noeuds
//serie[@nom=document('collection2.xml')//serie/@nom]
<personnes> <scenaristes> {//scenariste} </scenaristes> <dessinateurs> {//dessinateur} </dessinateurs> </personnes>
for $v1 in e1, $v2 in e2, ... let $w1 := e1', $w2 := e2', ... where condition order by eo1, eo2, ... return expr
ascending
ou descending
for $to in //tome let $ti := $to/titre where $to/@numero >= 3 order by $ti descending return <album> {$to/@numero} {$ti} <serie>{$to/../@nom}</serie> </album>
Précède l'expression (i.e. mettre au début du programme)
declare namespace nomprefixe="uri_espace_nommage";
declare default element namespace "uri_espace_nommage";
declare function nomQualifie ($arg1 as type1, $arg2 as type2, ...) as type_retour { corps de la fonction };
declare default function namespace "uri_espace_nommage";