+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
->
-<html xmlns="http://www.w3.org/1999/xhtml" >
- <head>
- <title>DOM</title>
-
- <meta http-equiv="Content-Type"
- content="text/html; charset=utf-8" />
- <meta name="copyright"
- content="Copyright © 2013 Kim Nguyễn" />
-
- <!-- Load jQuery -->
- <script src="../jquery-1.9.1.min.js" type="text/javascript" ></script>
- <!-- Load the library -->
- <script src="../simpleWebSlides.js" type="text/javascript" ></script>
-
- <link rel="stylesheet" href="../simpleWebSlides.css" type="text/css" media="all" />
- <!-- Load a custom Theme, the class-element marks this style-sheet
- a "theme" that can be swtiched dynamicaly -->
- <link class="sws-theme" rel="stylesheet" title="U-Psud style" href="../themes/uPsud.css" type="text/css" />
-
- <!-- Customize some templates and initialize -->
- <style type="text/css">
- .xml-tag { color: #00486c; }
- </style>
- <script type="text/javascript">
- <![CDATA[
- SWS.Config['sws-slide-change'] = SWS.Effects.slideChangeFadeOutIn;
- SWS.Config['sws-object-deactivate'] = SWS.Effects.objectDeactivateFadeOut;
- SWS.Config['sws-object-activate'] = SWS.Effects.objectActivateFadeIn;
-
- //Ensures that we load SWS at the very end, after MathJax has
- //been initialized
-
- $(window).load(function () {
- $(".inline-xml").each(function(i, elem)
- {
- var jelem = $(elem);
- var code = jelem.html();
- code = code.replace ("<![CDATA" + "[", "").replace ("]" + "]>", "");
- code = code.replace (/>/g, ">>>");
- code = code.replace (/</g, "<span class='xml-tag'><");
- code = code.replace (/>>>/g,"></span>");
-
- jelem.html(code);
- });
- });
-
- var checkSVG = function (o, i)
- {
- if (i >= 10 || SWS.Utils.isUndefined(o) || o == null) return;
- var svg = o.getSVGDocument();
- if (svg == null) {
- setTimeout(function() { checkSVG(o, i+1); }, 200);
- } else {
- var alltext = $(svg).find("text");
- alltext.css("font-family", "DIN");
- alltext.css("font-size", "70%");
-
- };
- };
- $(window).load(function() {
- $("embed").ready(function() {
- setTimeout(function() {
- $("embed").each(function(i, o) { checkSVG(this,0); });
-}, 1000);
- });
- });
- $(window).load(SWS.Presentation.init);
-
- ]]>
-
- </script>
-
- </head>
- <body>
- <a href="xpi_05.xhtml" class="sws-previous"/>
- <div class="sws-slide sws-cover sws-option-nofooter">
- <h1>XML et Programmation Internet</h1>
- <h1>Cours 6</h1>
- <a href="mailto:kn@lri.fr">kn@lri.fr</a>
- </div>
- <h1>Le modèle DOM</h1>
- <div class="sws-slide">
- <h1>Programmer avec XML</h1>
-<p>La représentation textuelles de documents XML n'est pas
- adaptée à la manipulation des données par un programme : </p>
-<ul>
- <li>On ne veut pas lire le fichier « caractère par caractère » </li>
- <li>On veut s'assurer que le fichier est bien formé et valide </li>
- <li>On veut pouvoir manipuler la structure d'arbre que représente le
- fichier </li>
-</ul>
-
- </div>
- <div class="sws-slide">
- <h1>Document Object Model</h1>
- <p>DOM est une <a>spécification</a> du W3C qui
- explique <a>comment</a> représenter un document dans un
- langage <a>orienté objet</a>.<br/>Avantages :
- </p>
- <ul>
- <li>N'est pas limité à un seul langage</li>
- <li>Permet de spécifier une API unique : programmer en XML en
- Java ou Python ne sera pas différent</li>
- </ul>
- <p>Inconvénivents :</p>
- <ul>
- <li>En pratique, orienté Java</li>
- <li>Se focalise sur les lanages objets de manière arbitraire</li>
- </ul>
- </div>
- <div class="sws-slide">
- <h1>Que définit le DOM ?</h1>
- <p>Le DOM définit des <a>interfaces</a> (c'est à dire, <a>des noms
- de classes</a> auquels sont associés
- des <a>propriétés</a>). Il définit aussi des types de bases
- (chaînes de caractères, entiers, etc.) et des types
- auxiliaires qui sont implantés par les types de bases du
- langage.
- </p>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Node</tt> (1/4, constantes) </h1>
- <code>
- //attention ce n'est pas du Java
- interface <a>Node</a> {
-
- //constantes entières définissant les types de nœuds
- const unsigned short <a>ELEMENT_NODE</a> = 1;
- const unsigned short <a>ATTRIBUTE_NODE</a> = 2;
- const unsigned short <a>TEXT_NODE</a> = 3;
- const unsigned short <a>CDATA_SECTION_NODE</a> = 4;
- const unsigned short <a>ENTITY_REFERENCE_NODE</a> = 5;
- const unsigned short <a>ENTITY_NODE</a> = 6;
- const unsigned short <a>PROCESSING_INSTRUCTION_NODE</a> = 7;
- const unsigned short <a>COMMENT_NODE</a> = 8;
- const unsigned short <a>DOCUMENT_NODE</a> = 9;
- const unsigned short <a>DOCUMENT_TYPE_NODE</a> = 10;
- const unsigned short <a>DOCUMENT_FRAGMENT_NODE</a> = 11;
- const unsigned short <a>NOTATION_NODE</a> = 12;
-
-
- </code>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Node</tt> (2/4, valeur, nom et type) </h1>
-
-
- <code>
- //nom et valeur du nœud
-
- readonly attribute DOMString <a>nodeName</a>;
- attribute DOMString <a>nodeValue</a>;
- </code>
- <ul>
- <li>Pour les éléments <tt>nodeValue</tt> vaut <tt>null</tt>
- et <tt>nodeName</tt> est le nom de la balise
- </li>
- <li>Pour les nœuds texte <tt>nodeValue</tt> est le texte
- et <tt>nodeName</tt> est la chaine fixe <tt>#text</tt>
- </li>
- <li>Pour les attributs <tt>nodeValue</tt> vaut la valeur de
- l'attribut et <tt>nodeName</tt> est son nom
- </li>
- </ul>
- <code>
- //L'une des 12 constantes du slide précédent
- readonly attribute unsigned short <a>nodeType</a>;
- </code>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Node</tt> (3/4, navigation) </h1>
- <code>
- readonly attribute Node <a>parentNode</a>;
- readonly attribute NodeList <a>childNodes</a>;
- readonly attribute Node <a>firstChild</a>;
- readonly attribute Node <a>lastChild</a>;
- readonly attribute Node <a>previousSibling</a>;
- readonly attribute Node <a>nextSibling</a>;
- readonly attribute NamedNodeMap <a>attributes</a>;
- </code>
- <p>Utilise deux interfaces auxiliaires:</p>
- <code>
- interface NodeList {
- Node <a>item(in unsigned long index)</a>;
- readonly attribute unsigned long <a>length</a>;
- };
- interface NamedNodeMap {
- Node <a>getNamedItem(in DOMString name)</a>;
- …
- }
- </code>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Node</tt> (4/4, mise à jour) </h1>
- <code>
- //Renvoie le document auquel appartient le nœud
- readonly attribute Document <a>ownerDocument</a>;
-
- Node <a>insertBefore(in Node newChild,
- in Node refChild)
- raises(DOMException)</a>;
-
- Node <a>replaceChild(in Node newChild,
- in Node oldChild)
- raises(DOMException)</a>;
- Node <a>removeChild(in Node oldChild)
- raises(DOMException)</a>;
- Node <a>appendChild(in Node newChild)
- raises(DOMException)</a>;
- boolean <a>hasChildNodes()</a>;
-
- //Nécessaire pour copier un nœud d'un document dans un autre
- Node <a>cloneNode(in boolean deep)</a>;
- </code>
- </div>
- <div class="sws-slide">
- <h1>Sous-interfaces de <tt>Node</tt></h1>
- <p>L'interface <tt>Node</tt> est spécialisées en 12
- sous-interfaces différents (les 12 types de nœuds
- possibles). Les principales sont:
- </p>
- <ul>
- <li><a><tt>Document</tt></a> : l'interface du nœud « racine » du
- document </li>
- <li><a><tt>Element</tt></a> : l'interface des nœuds
- correspondant à des balises</li>
- <li><a><tt>Attr</tt></a> : l'interface des nœuds
- correspondant à des attributs</li>
- <li><a><tt>Text</tt></a> : l'interface des nœuds
- correspondants à des textes </li>
- </ul>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Text</tt></h1>
- <code>
- interface Text : Node {
- //renvoie vrai si le nœud ne contient que des espaces
- readonly attribute boolean <a>isElementContentWhitespace</a>;
- …
- }
- </code>
- <p>(La spécification de DOM mentionne d'autres propriétés)</p>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Attr</tt></h1>
- <code>
- interface Attr : Node {
- readonly attribute DOMString <a>name</a>;
- readonly attribute DOMString <a>value</a>;
-
- readonly attribute Element <a>ownerElement</a>;
- …
- };
- </code>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Element</tt></h1>
- <code>
- interface Element : Node {
- readonly attribute DOMString <a>tagName</a>;
- //manipulation par chaine :
- DOMString <a>getAttribute(in DOMString name)</a>;
- void <a>setAttribute(in DOMString name,
- in DOMString value)
- raises(DOMException)</a>;
-
- void <a>removeAttribute(in DOMString name)
- raises(DOMException)</a>;
-
- //manipulation par nœud :
- Attr <a>getAttributeNode(in DOMString name)</a>;
- Attr <a>setAttributeNode(in Attr newAttr)
- raises(DOMException)</a>;
- Attr <a>removeAttributeNode(in Attr oldAttr)
- raises(DOMException)</a>;
-
- //renvoie tous les descendants avec un certain tag
- NodeList <a>getElementsByTagName(in DOMString name)</a>;
-
- }
- </code>
- </div>
- <div class="sws-slide">
- <h1>L'interface <tt>Document</tt></h1>
- <code>
- inteface Document : Node {
- //L'élément racine
- readonly attribute Element <a>documentElement</a>;
-
- //Création de nœuds pour ce document :
-
- Element <a>createElement(in DOMString tagName)
- raises(DOMException)</a>;
- Text <a>createTextNode(in DOMString data)</a>;
- Attr <a>createAttribute(in DOMString name)
- raises(DOMException)</a>;
-
- //Les descendants avec un tag particulier
- NodeList <a>getElementsByTagName(in DOMString tagname)</a>;
-
-
- //Copie un nœud, éventuellement avec ses descendants et
- //en fait un nœud ajoutable au document :
- Node <a>importNode(in Node importedNode,
- in boolean deep)</a>;
- </code>
- </div>
- <div class="sws-slide">
- <h1>Modèle mémoire</h1>
- <p>Un <a>nœud</a> (objet implémentant l'interface <tt>Node</tt>)
- ne peut pas appartenir à deux documents. Exemple : </p>
- <code>
- Node noeud_a = document1.getElementByTagName("a").item(0);
-
- <s>document2.appendChild(noeud_a);</s>//Exception si document2 n'est
- //pas le même objet que
- document1
- //par contre ceci est ok:
- document2.appendChild(<a>document2.importNode</a>(noeud_a, true));
- </code>
- </div>
- <h1>Java API for XML Processing</h1>
- <div class="sws-slide">
- <h1>Introduction à JAXP</h1>
- <p>API de la bibliothèque standard Java qui permet de manipuler
- du XML. Elle comprend (entre autres) :</p>
- <ul>
- <li>Lecture et écriture de documents <a>en streaming</a>
- (cours 7)</li>
- <li>Implémentation complète de la
- spécification <a>DOM</a></li>
- <li>Moteur XSLT (et donc XPath)</li>
- </ul>
- <p>Inconvénients : la bibliothèque essaye d'être très générique,
- afin que n'importe qui puisse fournir son implémentation de DOM
- en utilisant les interfaces fournies. Il faut donc parfois
- passer par des grandes séquences d'incatations magiques pour
- créer un objet</p>
- </div>
- <div class="sws-slide">
- <h1>Structure de l'API</h1>
- <ul>
- <li>Les types et interfaces spécifiés par le w3C se trouvent
- dans le packages <tt>org.w3c.*</tt> </li>
- <li>Les types « usuels» pour XML sont
- dans <tt>org.xml.*</tt></li>
- <li>Les <a>classes</a> concrètes java implémentant les
- interfaces sont dans <tt>javax.xml.*</tt></li>
- </ul>
- </div>
- <div class="sws-slide">
- <h1><tt>Factory</tt> <i>design pattern</i></h1>
- <p>Comme toutes les API complexes en Java (et dans les langages
- objets en général), Jaxp utilise le <i>design pattern</i>
- de <a>Factory</a>. </p>
- <p>Pour créer un objet de type <tt>Foo</tt> on ne fait pas
- simplement <tt>new Foo(…);</tt> mais on utilise une
- classe <tt>FooFactory</tt> qui possède une
- méthode <tt>.createFoo(…)</tt>
- </p>
- <p >Dans quel cas est-ce intéressant ?</p>
- <p class="sws-pause">Quand <tt>Foo</tt> est une interface. On
- ne peut pas faire <tt>new</tt> sur une interface. Il faut donc
- une méthode pour appeler le constructeur de la classe
- implémentant <tt>Foo</tt> puis qui le caste en <tt>Foo</tt> … </p>
-
- </div>
- <div class="sws-slide">
- <h1><tt>Factory</tt> <i>design pattern</i> (exemple) </h1>
- <img style="margin-left:10%;width:80%" src="factory_pattern_uml_diagram.jpg" />
- </div>
- <div class="sws-slide">
- <h1>Création d'un document : <tt>DocumentBuilder</tt></h1>
- <p>La classe <tt>DocumentBuilder</tt> permet de créer un
- document XML : </p>
- <ul><li>Soit en le lisant depuis un fichier (avec la
- méthode <tt>parse()</tt></li>
- <li>Soit vide, avec la méthode <tt>newDocument()</tt></li>
- </ul>
- <p>Pour obtenir un <tt>DocumentBuidler</tt>, il faut passer par
- un <tt>DocumentBuilderFactory</tt> : </p>
- <code>
- //création de la Factory
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
-
- //On définit quelques options
- dbf.setIgnoringElementContentWhitespace(true); // option
- dbf.setValidating(false); // option
-
- //On crée le documentBuilder
- DocumentBuilder db = dbf.newDocumentBuilder();
-
- //On charge le document
- Document doc = db.parse("fichier.xml");
- </code>
- </div>
- <div class="sws-slide">
- <h1>DOM dans JAXP</h1>
- <p>Le <tt>DocumentBuilder</tt> permet d'obtenir
- un <tt>Document</tt> (interface Java qui implémente l'interface DOM
- du même nom)</p>
- <p><a>Conventions de nommage :</a> les <i>propriétés</i> des
- interfaces DOM sont préfixées par <tt>get</tt> ou <tt>set</tt>
- en Java. Les méthodes ont le même nom. Exemple :</p>
- <code>
- Node n = …;
- n.getNodeType(); //DOM défini nodeType;
- n.getFirstChild(); //DOM défini firstChild;
- n.appendChild(m); //C'est une méthode en DOM donc même nom
- </code>
- </div>
- <div class="sws-slide">
- <h1>Conversions</h1>
- <p>On travaille la plupart du temps avec des objets ayant le
- type <tt>Node</tt>. La manière correcte de les convertir est la
- suivante :
- </p>
- <code>
- switch (n.getNodeType()) {
-
- case Node.DOCUMENT_NODE:
- Document d = (Document) n;
- …
- break;
- case Node.ELEMENT_NODE:
- Element e = (Element) n;
- …
- break;
- case Node.TEXT_NODE:
- Text t = (Text) n;
- …
- break;
- }
- </code>
- </div>
- <div class="sws-slide">
- <h1>Rappels : classes et interfaces utiles en Java</h1>
- <p> Interface <tt>Map<K,V></tt> permet d'associer des
- clés de types <tt>K</tt> à des valeurs de type <tt>V</tt>
- (<tt>K</tt> et <tt>V</tt> doivent être des <tt>Objects</tt> donc
- pas <tt>int</tt>, <tt>bool</tt> , …)</p>
- <p>Implémentations possibles
- : <tt>TreeMap</tt>, <tt>HashMap</tt></p>
-
- </div>
- </body>
-</html>