.
[hacks/simpleWebSlides.git] / xpi / xpi_06.xhtml
1 <?xml version="1.0" encoding="utf-8" ?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
4 >
5 <html xmlns="http://www.w3.org/1999/xhtml" >
6   <head>
7     <title>DOM</title>
8
9     <meta http-equiv="Content-Type"
10           content="text/html; charset=utf-8" />
11     <meta name="copyright"
12           content="Copyright &#169; 2013 Kim Nguyễn" />
13
14     <!-- Load jQuery -->
15     <script src="../jquery-1.9.1.min.js" type="text/javascript" ></script>
16     <!-- Load the library -->
17     <script src="../simpleWebSlides.js" type="text/javascript" ></script>
18
19     <link rel="stylesheet" href="../simpleWebSlides.css" type="text/css"  media="all" />
20     <!-- Load a custom Theme, the class-element marks this style-sheet
21       a "theme" that can be swtiched dynamicaly -->
22     <link class="sws-theme" rel="stylesheet"  title="U-Psud style"  href="../themes/uPsud.css" type="text/css" />
23
24     <!-- Customize some templates and initialize -->
25     <style type="text/css">
26       .xml-tag { color: #00486c; }
27     </style>
28     <script type="text/javascript">
29       <![CDATA[
30       SWS.Config['sws-slide-change'] = SWS.Effects.slideChangeFadeOutIn;
31       SWS.Config['sws-object-deactivate'] =  SWS.Effects.objectDeactivateFadeOut;
32       SWS.Config['sws-object-activate'] = SWS.Effects.objectActivateFadeIn;
33
34       //Ensures that we load SWS at the very end, after MathJax has
35       //been initialized
36
37       $(window).load(function () {
38        $(".inline-xml").each(function(i, elem)
39       {
40       var jelem = $(elem);
41       var code = jelem.html();
42       code = code.replace ("<![CDATA" + "[", "").replace ("]" + "]>", "");
43       code = code.replace (/>/g, ">>>");
44       code = code.replace (/</g, "<span class='xml-tag'>&lt;");
45       code = code.replace (/>>>/g,"&gt;</span>");
46
47       jelem.html(code);
48       });
49   });
50
51       var checkSVG = function (o, i)
52       {
53             if (i >= 10 || SWS.Utils.isUndefined(o) || o == null) return;
54             var svg = o.getSVGDocument();
55             if (svg == null) {
56               setTimeout(function() { checkSVG(o, i+1); }, 200);
57             } else {
58          var alltext = $(svg).find("text");
59          alltext.css("font-family", "DIN");
60          alltext.css("font-size", "70%");
61
62             };
63       };
64       $(window).load(function() {
65       $("embed").ready(function() {
66          setTimeout(function() {
67          $("embed").each(function(i, o) { checkSVG(this,0);   });
68 }, 1000);
69         });
70      });
71       $(window).load(SWS.Presentation.init);
72
73         ]]>
74
75     </script>
76
77   </head>
78   <body>
79     <a href="xpi_05.xhtml" class="sws-previous"/>
80     <div class="sws-slide sws-cover sws-option-nofooter">
81       <h1>XML et Programmation Internet</h1>
82       <h1>Cours 6</h1>
83       <a href="mailto:kn@lri.fr">kn@lri.fr</a>
84     </div>
85     <h1>Le modèle DOM</h1>
86     <div class="sws-slide">
87       <h1>Programmer avec XML</h1>
88 <p>La représentation textuelles de documents XML n'est pas
89   adaptée à la manipulation des données par un programme : </p>
90 <ul>
91   <li>On ne veut pas lire le fichier « caractère par caractère » </li>
92   <li>On veut s'assurer que le fichier est bien formé et valide </li>
93   <li>On veut pouvoir manipuler la structure d'arbre que représente le
94     fichier </li>
95 </ul>
96
97     </div>
98     <div class="sws-slide">
99       <h1>Document Object Model</h1>
100       <p>DOM est une <a>spécification</a> du W3C qui
101         explique <a>comment</a> représenter un document dans un
102         langage <a>orienté objet</a>.<br/>Avantages :
103       </p>
104       <ul>
105         <li>N'est pas limité à un seul langage</li>
106         <li>Permet de spécifier une API unique : programmer en XML en
107           Java ou Python ne sera pas différent</li>
108       </ul>
109       <p>Inconvénivents :</p>
110       <ul>
111         <li>En pratique, orienté Java</li>
112         <li>Se focalise sur les lanages objets de manière arbitraire</li>
113       </ul>
114     </div>
115     <div class="sws-slide">
116       <h1>Que définit le DOM ?</h1>
117       <p>Le DOM définit des <a>interfaces</a> (c'est à dire, <a>des noms
118           de classes</a> auquels sont associés
119           des <a>propriétés</a>). Il définit aussi des types de bases
120           (chaînes de caractères, entiers, etc.) et des types
121           auxiliaires qui sont implantés par les types de bases du
122           langage.
123       </p>
124     </div>
125     <div class="sws-slide">
126       <h1>L'interface <tt>Node</tt> (1/4, constantes) </h1>
127       <code>
128         //attention ce n'est pas du Java
129         interface <a>Node</a> {
130
131         //constantes entières définissant les types de nœuds
132         const unsigned short      <a>ELEMENT_NODE</a>                   = 1;
133         const unsigned short      <a>ATTRIBUTE_NODE</a>                 = 2;
134         const unsigned short      <a>TEXT_NODE</a>                      = 3;
135         const unsigned short      <a>CDATA_SECTION_NODE</a>             = 4;
136         const unsigned short      <a>ENTITY_REFERENCE_NODE</a>          = 5;
137         const unsigned short      <a>ENTITY_NODE</a>                    = 6;
138         const unsigned short      <a>PROCESSING_INSTRUCTION_NODE</a>    = 7;
139         const unsigned short      <a>COMMENT_NODE</a>                   = 8;
140         const unsigned short      <a>DOCUMENT_NODE</a>                  = 9;
141         const unsigned short      <a>DOCUMENT_TYPE_NODE</a>             = 10;
142         const unsigned short      <a>DOCUMENT_FRAGMENT_NODE</a>         = 11;
143         const unsigned short      <a>NOTATION_NODE</a>                  = 12;
144
145
146       </code>
147     </div>
148     <div class="sws-slide">
149       <h1>L'interface <tt>Node</tt> (2/4, valeur, nom et type) </h1>
150
151
152       <code>
153         //nom et valeur du nœud
154
155         readonly attribute DOMString       <a>nodeName</a>;
156         attribute DOMString                <a>nodeValue</a>;
157       </code>
158       <ul>
159         <li>Pour les éléments <tt>nodeValue</tt> vaut <tt>null</tt>
160           et <tt>nodeName</tt> est le nom de la balise
161         </li>
162         <li>Pour les nœuds texte <tt>nodeValue</tt> est le texte
163           et <tt>nodeName</tt> est la chaine fixe <tt>#text</tt>
164         </li>
165         <li>Pour les attributs <tt>nodeValue</tt> vaut la valeur de
166           l'attribut et <tt>nodeName</tt> est son nom
167         </li>
168         </ul>
169       <code>
170         //L'une des 12 constantes du slide précédent
171         readonly attribute unsigned short  <a>nodeType</a>;
172       </code>
173     </div>
174     <div class="sws-slide">
175       <h1>L'interface <tt>Node</tt> (3/4, navigation) </h1>
176       <code>
177         readonly attribute Node            <a>parentNode</a>;
178         readonly attribute NodeList        <a>childNodes</a>;
179         readonly attribute Node            <a>firstChild</a>;
180         readonly attribute Node            <a>lastChild</a>;
181         readonly attribute Node            <a>previousSibling</a>;
182         readonly attribute Node            <a>nextSibling</a>;
183         readonly attribute NamedNodeMap    <a>attributes</a>;
184       </code>
185       <p>Utilise deux interfaces auxiliaires:</p>
186       <code>
187         interface NodeList {
188         Node               <a>item(in unsigned long index)</a>;
189         readonly attribute unsigned long   <a>length</a>;
190         };
191         interface NamedNodeMap {
192         Node               <a>getNamedItem(in DOMString name)</a>;
193         …
194         }
195       </code>
196     </div>
197     <div class="sws-slide">
198       <h1>L'interface <tt>Node</tt> (4/4, mise à jour) </h1>
199       <code>
200         //Renvoie le document auquel appartient le nœud
201         readonly attribute Document        <a>ownerDocument</a>;
202
203         Node               <a>insertBefore(in Node newChild, 
204                                            in Node refChild)
205                                         raises(DOMException)</a>;
206
207         Node               <a>replaceChild(in Node newChild, 
208                                         in Node oldChild)
209                                         raises(DOMException)</a>;
210         Node               <a>removeChild(in Node oldChild)
211                                         raises(DOMException)</a>;
212         Node               <a>appendChild(in Node newChild)
213                                         raises(DOMException)</a>;
214         boolean            <a>hasChildNodes()</a>;
215
216         //Nécessaire pour copier un nœud d'un document dans un autre
217         Node               <a>cloneNode(in boolean deep)</a>;
218       </code>
219     </div>
220     <div class="sws-slide">
221       <h1>Sous-interfaces de <tt>Node</tt></h1>
222       <p>L'interface <tt>Node</tt> est spécialisées en 12
223       sous-interfaces différents (les 12 types de nœuds
224       possibles). Les principales sont:
225       </p>
226       <ul>
227         <li><a><tt>Document</tt></a> : l'interface du nœud « racine » du
228         document </li>
229         <li><a><tt>Element</tt></a> : l'interface des nœuds
230         correspondant à des balises</li>
231         <li><a><tt>Attr</tt></a> : l'interface des nœuds
232         correspondant à des attributs</li>
233         <li><a><tt>Text</tt></a> : l'interface des nœuds
234         correspondants à des textes </li>
235       </ul>
236     </div>
237     <div class="sws-slide">
238       <h1>L'interface <tt>Text</tt></h1>
239       <code>
240         interface Text : Node {
241         //renvoie vrai si le nœud ne contient que des espaces
242         readonly attribute boolean         <a>isElementContentWhitespace</a>;
243         …
244         }
245       </code>
246       <p>(La spécification de DOM mentionne d'autres propriétés)</p>
247     </div>
248     <div class="sws-slide">
249       <h1>L'interface <tt>Attr</tt></h1>
250       <code>
251         interface Attr : Node {
252         readonly attribute DOMString       <a>name</a>;
253         readonly attribute DOMString       <a>value</a>;
254
255         readonly attribute Element         <a>ownerElement</a>;
256         …
257         };
258       </code>
259     </div>
260     <div class="sws-slide">
261       <h1>L'interface <tt>Element</tt></h1>
262       <code>
263         interface Element : Node {
264         readonly attribute DOMString       <a>tagName</a>;
265         //manipulation par chaine :
266         DOMString          <a>getAttribute(in DOMString name)</a>;
267         void               <a>setAttribute(in DOMString name, 
268                                         in DOMString value)
269                                         raises(DOMException)</a>;
270
271         void               <a>removeAttribute(in DOMString name)
272                                         raises(DOMException)</a>;
273
274         //manipulation par nœud :
275         Attr               <a>getAttributeNode(in DOMString name)</a>;
276         Attr               <a>setAttributeNode(in Attr newAttr)
277                                         raises(DOMException)</a>;
278         Attr               <a>removeAttributeNode(in Attr oldAttr)
279                                         raises(DOMException)</a>;
280
281         //renvoie tous les descendants avec un certain tag
282         NodeList           <a>getElementsByTagName(in DOMString name)</a>;
283
284         }
285       </code>
286     </div>
287     <div class="sws-slide">
288       <h1>L'interface <tt>Document</tt></h1>
289       <code>
290         inteface Document : Node {
291         //L'élément racine
292         readonly attribute Element         <a>documentElement</a>;
293
294         //Création de nœuds pour ce document :
295
296         Element            <a>createElement(in DOMString tagName)
297                                         raises(DOMException)</a>;
298         Text               <a>createTextNode(in DOMString data)</a>;
299         Attr               <a>createAttribute(in DOMString name)
300                                         raises(DOMException)</a>;
301
302         //Les descendants avec un tag particulier
303         NodeList           <a>getElementsByTagName(in DOMString tagname)</a>;
304
305
306         //Copie un nœud, éventuellement avec ses descendants et
307         //en fait un nœud ajoutable au document :
308         Node               <a>importNode(in Node importedNode, 
309                                 in boolean deep)</a>;
310       </code>
311     </div>
312     <div class="sws-slide">
313       <h1>Modèle mémoire</h1>
314       <p>Un <a>nœud</a> (objet implémentant l'interface <tt>Node</tt>)
315       ne peut pas appartenir à deux documents. Exemple : </p>
316       <code>
317         Node noeud_a = document1.getElementByTagName("a").item(0);
318
319         <s>document2.appendChild(noeud_a);</s>//Exception si document2 n'est
320                                        //pas le même objet que
321                                        document1
322         //par contre ceci est ok:
323         document2.appendChild(<a>document2.importNode</a>(noeud_a, true));
324       </code>
325     </div>
326     <h1>Java API for XML Processing</h1>
327     <div class="sws-slide">
328       <h1>Introduction à JAXP</h1>
329       <p>API de la bibliothèque standard Java qui permet de manipuler
330       du XML. Elle comprend (entre autres) :</p>
331       <ul>
332         <li>Lecture et écriture de documents <a>en streaming</a>
333         (cours 7)</li>
334         <li>Implémentation complète de la
335         spécification <a>DOM</a></li>
336         <li>Moteur XSLT (et donc XPath)</li>
337       </ul>
338       <p>Inconvénients : la bibliothèque essaye d'être très générique,
339       afin que n'importe qui puisse fournir son implémentation de DOM
340       en utilisant les interfaces fournies. Il faut donc parfois
341       passer par des grandes séquences d'incatations magiques pour
342       créer un objet</p>
343     </div>
344     <div class="sws-slide">
345       <h1>Structure de l'API</h1>
346       <ul>
347         <li>Les types et interfaces spécifiés par le w3C se trouvent
348         dans le packages <tt>org.w3c.*</tt> </li>
349         <li>Les types « usuels» pour XML sont
350         dans <tt>org.xml.*</tt></li>
351         <li>Les <a>classes</a> concrètes java implémentant les
352         interfaces sont dans <tt>javax.xml.*</tt></li>
353       </ul>
354     </div>
355     <div class="sws-slide">
356       <h1><tt>Factory</tt> <i>design pattern</i></h1>
357       <p>Comme toutes les API complexes en Java (et dans les langages
358         objets en général), Jaxp utilise le <i>design pattern</i>
359         de <a>Factory</a>. </p>
360       <p>Pour créer un objet de type <tt>Foo</tt> on ne fait pas
361       simplement <tt>new Foo(…);</tt> mais on utilise une
362       classe <tt>FooFactory</tt> qui possède une
363       méthode <tt>.createFoo(…)</tt>
364       </p>
365       <p >Dans quel cas est-ce intéressant ?</p>
366       <p class="sws-pause">Quand <tt>Foo</tt> est une interface. On
367       ne peut pas faire <tt>new</tt> sur une interface. Il faut donc
368       une méthode pour appeler le constructeur de la classe
369       implémentant <tt>Foo</tt> puis qui le caste en <tt>Foo</tt> … </p>
370
371     </div>
372     <div class="sws-slide">
373       <h1><tt>Factory</tt> <i>design pattern</i> (exemple) </h1>
374       <img style="margin-left:10%;width:80%" src="factory_pattern_uml_diagram.jpg" />
375     </div>
376     <div class="sws-slide">
377       <h1>Création d'un document : <tt>DocumentBuilder</tt></h1>
378       <p>La classe <tt>DocumentBuilder</tt> permet de créer un
379       document XML : </p>
380       <ul><li>Soit en le lisant depuis un fichier (avec la
381           méthode <tt>parse()</tt></li>
382         <li>Soit vide, avec la méthode <tt>newDocument()</tt></li>
383       </ul>
384       <p>Pour obtenir un <tt>DocumentBuidler</tt>, il faut passer par
385         un <tt>DocumentBuilderFactory</tt> : </p>
386       <code>
387         //création de la Factory
388         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
389
390         //On définit quelques options
391         dbf.setIgnoringElementContentWhitespace(true); // option
392         dbf.setValidating(false); // option
393
394         //On crée le documentBuilder
395         DocumentBuilder db = dbf.newDocumentBuilder();
396
397         //On charge le document
398         Document doc = db.parse("fichier.xml");
399       </code>
400     </div>
401     <div class="sws-slide">
402       <h1>DOM dans JAXP</h1>
403       <p>Le <tt>DocumentBuilder</tt> permet d'obtenir
404       un <tt>Document</tt> (interface Java qui implémente l'interface DOM
405       du même nom)</p>
406       <p><a>Conventions de nommage :</a> les <i>propriétés</i> des
407       interfaces DOM sont préfixées par <tt>get</tt> ou <tt>set</tt>
408       en Java. Les méthodes ont le même nom. Exemple :</p>
409       <code>
410         Node n = …;
411         n.getNodeType(); //DOM défini nodeType;
412         n.getFirstChild(); //DOM défini firstChild;
413         n.appendChild(m);  //C'est une méthode en DOM donc même nom
414       </code>
415     </div>
416     <div class="sws-slide">
417       <h1>Conversions</h1>
418       <p>On travaille la plupart du temps avec des objets ayant le
419         type <tt>Node</tt>. La manière correcte de les convertir est la
420         suivante :
421       </p>
422       <code>
423         switch (n.getNodeType()) {
424
425         case Node.DOCUMENT_NODE:
426            Document d = (Document) n;
427            …
428            break;
429         case Node.ELEMENT_NODE:
430            Element e = (Element) n;
431            …
432            break;
433         case Node.TEXT_NODE:
434            Text t = (Text) n;
435            …
436            break;
437         }
438       </code>
439     </div>
440   </body>
441 </html>