+++ /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>XPath et XSLT en Java</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_06.xhtml" class="sws-previous"/>
- <div class="sws-slide sws-cover sws-option-nofooter">
- <h1>XML et Programmation Internet</h1>
- <h1>Cours 7</h1>
- <a href="mailto:kn@lri.fr">kn@lri.fr</a>
- </div>
- <h1>Requêtes XPath en Java</h1>
- <div class="sws-slide">
- <h1>Moteur XPath en java</h1>
- <p>L'API JAXP contient un moteur XPath 1.0 complet. Outre les
- classes nécessaires au chargement de fichier et à la
- manipulation du DOM (voir cours 6), il faut charger les éléments
- du package <a><tt>javax.xml.xpath</tt></a>. Comme pour le reste
- de JAXP, on passe par un <tt>XPathFactory</tt> pour créer une
- nouvelle instance du moteur XPath.
- </p>
- </div>
- <div class="sws-slide">
- <h1>Exemple : packages</h1>
- <code style="background:white;"> //Pour les documents et DOM
- <kbd>import org.w3c.dom.*;
- import javax.xml.namespace.QName;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;</kbd>
-
- //Pour le moteur XPath
- <u>import javax.xml.xpath.XPathFactory;
- import javax.xml.xpath.XPath;
- import javax.xml.xpath.XPathConstants;</u>
-
- <kbd>public class TestXPath {</kbd>
- //Deux attributs pour contenir le moteur XPath et le document builder
- <kbd>XPath xp_ = null;
- DocumentBuilder db_ = null;</kbd>
-
- </code>
- </div>
- <div class="sws-slide">
- <h1>Exemple : constructeur</h1>
- <code style="background:white;"> <kbd>public TestXPath () {
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- db_ = factory.newDocumentBuilder();
-
- <u>XPathFactory xf = XPathFactory.newInstance();
- xp_ = xf.newXPath();</u>
-
- } catch (Exception e) {</kbd>
- //Peuvent être levées en cas d'erreur de création d'objet XPath
- //DocumentBuilder, par exemple si des options passées sont
- //non-supportées.
-<kbd> }
- }</kbd>
-
- </code>
- </div>
-<div class="sws-slide">
- <h1>Exemple : méthode d'évaluation</h1>
- <code style="background:white;">
- <kbd>NodeList eval(String fichier, String chemin) throws Exception {
-
- </kbd>//Création d'un DOM pour le fichier source<kbd>
- Document doc = db_.parse(fichier);
-
- <u>NodeList nl = (NodeList) xp_.evaluate(chemin,
- doc,
- XPathConstants.NODESET);</u>
-
-
- }</kbd>
-
-</code>
-</div>
-<div class="sws-slide">
- <h1>Méthode <tt>XPath.evaluate()</tt></h1>
-<p>La méthode <tt>XPath.evaluate(xpath, n, type)</tt> permet d'évaluer une
- l'expression <a>xpath</a> (donnée sous-forme de chaîne de
- caractères), à partir du nœud contexte <tt>n</tt> (qui doit
- implémenter l'interface <a>Node</a>). Le résultat est de
- type <a>typ</a>. La fonction renvoie un résultat de
- type <s>Object</s>. L'argument <tt>typ</tt> peut avoir 5 valeurs
- possibles, définies dans la class <tt>XPathConstants</tt> :
-</p>
-<ul>
- <li><tt><u>XPathConstants.BOOLEAN</u></tt>: le résultat est de type java <tt>Boolean</tt></li>
- <li><tt><u>XPathConstants.NUMBER</u></tt>: le résultat est de type java <tt>Double</tt></li>
- <li><tt><u>XPathConstants.STRING</u></tt>: le résultat est de type java <tt>String</tt></li>
- <li><tt><u>XPathConstants.NODE</u></tt>: le résultat est de type java <tt>Node</tt></li>
- <li><tt><u>XPathConstants.NODESET</u></tt>: le résultat est de type java <tt>NodeList</tt></li>
-</ul>
-<p>En effet, une expression XPath peut avoir comme valeur un booléen,
- un ensemble de noeuds ou une chaîne dépendant du <s>contexte</s> où
- elle est utilisée. On peut demander à Jaxp d'évaluer la requête
- XPath pour un certain contexte.
-</p>
-</div>
- <div class="sws-slide">
- <h1>Exemple </h1>
- <code><kbd> Document doc = ...
- String chemin = <u>"//descendant::year[position () = 1]";</u>
-
-
- </kbd>//Crée une NodeList à un élément<kbd>
- <u>NodeList nl = (NodeList) xp_.evaluate(chemin, doc, XPathConstants.NODESET);</u>
-
- </kbd>//Renvoie le nœud correspondant ou null<kbd>
- <u>Node n = (Node) xp_.evaluate(chemin, doc, XPathConstants.NODE);</u>
-
- </kbd>//Renvoie le double java correspondant à la valeur<kbd>
- <u>Double d = (Double) xp_.evaluate(chemin, doc, XPathConstants.NUMBER);</u>
-
- </kbd>//Renvoie la chaine java correspondant au texte<kbd>
- <u>String s = (String) xp_.evaluate(chemin, doc, XPathConstants.STRING);</u>
-
- </kbd>//Renvoie la valeur de vérité corresondant au chemin<kbd>
- <u>Boolean b = (Boolean) xp_.evaluate(chemin, doc, XPathConstants.BOOLEAN);</u>
-</kbd></code>
-</div>
-<div class="sws-slide">
-<h1>La classe <tt>XPathExpression</tt></h1>
-<p>Cette classe est similaire à l'utilisation
- de <a>PreparedStatements</a> en JDBC.<br/>
-<span class="sws-pause">Utilité ?</span>
-<span class="sws-pause">compiler la requête XPath une fois pour toute
- et donc éviter de re-parser la chaîne de caractère à chaque
- appel. <br/>Exemple : </span>
-</p>
-<code>
-<kbd> <u>XPathExpression ex = xp_.compile("//movie/title");</u>
-
- NodeList nl1 = (NodeList) ex.evaluate(doc1, XPathConstants.NODESET);
- NodeList nl2 = (NodeList) ex.evaluate(doc2, XPathConstants.NODESET);
- NodeList nl3 = (NodeList) ex.evaluate(doc3, XPathConstants.NODESET);
- …
-</kbd></code>
-
-</div>
-<h1>XSLT</h1>
-<div class="sws-slide">
-<h1> Applications de transformations XSLT </h1>
-<p>Appliquer une transformation XSLT est une opération complexe à
- cause des différentes combinaisons possibles :
-</p>
-<ul>
-<li>Le fichier source (ex: <tt>movie.xml</tt>) peut être soit déjà
- chargé comme un <tt>DOM</tt>, soit sous forme de fichier, soit sous
- forme de chaîne de caractères,…</li>
-<li>Le fichier destination (ex: <tt>resultat.xhtml</tt>) est
- représenté par une <tt>DOM</tt> qui doit être
- éventuellement <i>sérialisé</i> (i.e. retransformé en fichier XML).
-</li>
-<li>La transformation elle même (ex: <tt>style.xsl</tt>) peut être
- sous forme diverse (fichier, URL, DOM, …)
-</li>
-<p>On a donc une série de classes d'encapsulation (<tt>Source</tt>,
- …), de factory, …</p>
-</ul>
-
-
-</div>
-<div class="sws-slide">
-<h1>Création d'une transformation</h1>
-<p>Pour créer une transformation XSLT, il faut les classes suivantes,
- du package: <tt>javax.xml.transform</tt></p>
-<code>
- //La classe permettant d'appliquer une transformation XSLT
- //ainsi que sa factory
- <u>import javax.xml.transform.Transformer;
- import javax.xml.transform.TransformerFactory;</u>
-
- //La classe permettant de charger des transformations ou des
- //arguments de transformation sous forme de fichiers
- <u>import javax.xml.transform.stream.StreamSource;</u>
-
- //La classe permettant de charger des documents ou transformations
- //sous forme de nœuds DOM
- <u>import javax.xml.transform.dom.DOMSource;</u>
-
-</code>
-</div>
-
-<div class="sws-slide">
- <h1>Exemple</h1>
-
-<code>
- <u>TransformerFactory tf = TransformerFactory.newInstance();</u>
- //On crée un StreamSource à partir d'un nom de fichier contenant
- //la feuille de style XSLT
- <u>Transformer tr = tf.newTransformer(new StreamSource("style.xsl"));</u>
-</code>
-
-<p>Le code ci-dessus crée un objet de type <tt>Transformer</tt>
- représentant la transformation XSLT se trouvant dans le fichier
- <tt>style.xsl</tt>. <br/>
- Si on avait chargé le fichier sous forme d'un
- arbre DOM:
-</p>
-<code> <kbd>Document style_xsl = … ;</kbd>//chargement de style.xsl
-
- <u>TransformerFactory tf = TransformerFactory.newInstance();</u>
- <u>Transformer tr = tf.newTransformer(new DOMSource(style_xsl));</u>
-
-</code>
-
-</div>
-<div class="sws-slide">
-<h1>La méthode <tt>Transformer.transform()</tt></h1>
-<code> transform(<u>Source</u> xmlSource, <u>Result</u> outputTarget)
-</code>
-<p>Les interfaces <tt>Source</tt> et <tt>Result</tt> permettent
- d'abstraire le type de l'entrée et de la sortie. Ces dernières
- peuvent être :</p>
-<ul>
- <li>Des objets DOM : <u>DOMSource</u> et <u>DOMResult</u> </li>
- <li>Des objets d'entrée sortie de la bibliothèque java standard
- (<tt>File</tt>, <tt>Input/OutputStream</tt>, <tt>Reader/Writer</tt>,
- chaîne de caractère représentant un nom de fichier
- : <u>StreamSource</u> et <u>StreamResult</u></li>
-</ul>
-
-</div>
-<div class="sws-slide">
-<h1>Exemple</h1>
-<code>
- //On applique le transformer associé à style.xsl
- //sur le fichier movie et on écrit le résultat sur
- //la sortie standard :
-
- <u>tr.transform(new StreamSource("movies.xml"), new StreamResult(System.out));</u>
-</code>
-</div>
-<div class="sws-slide">
- <h1>Sérialisation</h1>
- <p>La manière la plus simple de <i>sérialiser un document</i> est de
- créer une transformation XSLT vide (i.e qui fait l'identité) et de
- demander à ce que le résultat soit un fichier (ou la sortie
- standard)</p>
- <code>
- <kbd>Document doc = …; </kbd>//l'objet DOM que l'on veut sauver dans un fichier
- <u>Transformer tr = tf.newTransformer();</u>
- <u>tr.transform(new DOMSource(doc),</u>
- <u>new StreamResult(new FileOutputStream("fichier.xml")));</u>
- </code>
-</div>
-<h1><i>Streaming</i> avec SAX</h1>
-<div class="sws-slide">
- <h1><i>Streaming</i> ?</h1>
- <p>Charger un document avec DOM permet d'accéder à l'arbre « en
- entier » mais peut être couteux en mémoire (chaque nœud possède au
- moins 4 pointeurs, 2 chaines de caractères, …). On veut pouvoir
- effectuer certains types d'opération à la volée :
- </p>
- <ul class="sws-pause">
- <li class="sws-pause">Faire des statistiques sur les documents (compter le nombre
- d'éléments, d'attributs, …)</li>
- <li class="sws-pause">Faire des transformations simples qui
- préservent la structure (par exemple mettre les balises en
- majuscules)</li>
- <li class="sws-pause">Valider vis à vis d'une DTD</li>
- </ul>
-</div>
-<div class="sws-slide">
-<h1>Programmation évènementielle</h1>
-<p>Les parseurs SAX (Simple API for XML) reposent sur la programmation
- évènementielle. Ils lisent le fichier d'entrée et génèrent un
- certain nombre d'évènements, auxquels on peut réagir avec du code.
- Les évènements sont :
-</p>
-<ul>
- <li>Début de document</li>
- <li>Fin de document </li>
- <li>Ouverture de balise (avec le nom et la liste des attributs)</li>
- <li>Fermeture de balise (avec le nom)</li>
- <li>Élément texte</li>
- <li>Commentaire </li>
- <li>…</li>
-</ul>
-</div>
-<div class="sws-slide">
- <h1>L'API SAX</h1>
-<code>
-import javax.xml.parsers.*;
-import org.xml.sax.*;
-import org.xml.sax.helpers.*;
-</code>
-<p>On doit étendre la classe par <tt>DefaultHandler</tt></p>
-</div>
-<div class="sws-slide">
-<h1><tt>DefaultHandler</tt></h1>
-<code>
- //le parseur a lu length caractères qui se trouvent dans
- //ch à partir de la position start
- void <u>characters</u>(char[] ch, int start, int length)
-
- //le parseur a détécté la fin de document
- void <u>endDocument</u>()
-
- //le parseur a détecté la fin d'un élément
- void <u>endElement</u>(String uri, String localName, String qName)
-
- //le parseur a détecté du texte « ignorable »
- void <u>ignorableWhitespace</u>(char[] ch, int start, int length)
-
- //le parseur a détecté le début du document
- void <u>startDocument</u>()
- //le parseur a detecté le début d'un élément
- void <u>startElement</u>(String uri,String localName, String qName,
- Attributes attributes)
-</code>
-<p><tt><u>Attributes</u></tt> est une classe auxiliaire qui permet de
- connaître le nom, le nombre et les valeurs des attributs pour cette
- balise.</p>
-</div>
-
-<div class="sws-slide">
-<h1><tt>Handler</tt> personnalisé</h1>
-<p>On étend la classe <tt>DefaultHandler</tt> : </p>
-<code>
-<u>class MyHandler extends DefaultHandler</u> {
- private int nb_elems;
- MyHandler() {
- nb_elems = 0;
- }
- void <u>startElement</u>(String uri,String localName, String qName,
- Attributes attributes)
- throws SAXException {
- nb_elems++;
-
- }
- int getNbElems() { return nb_elems; };
-}
-
-</code>
-
-</div>
-<div class="sws-slide">
-<h1>Invocation du parseur</h1>
-<p>On utilise (encore) une factory : </p>
-<code>
- public static void main(String[] args) {
- …
- SAXParserFactory spf = <u>SAXParserFactory.newInstance</u>();
- spf.setNamespaceAware(true);
- SAXParser saxParser = <u>spf.newSAXParser</u>();
-
- MyHandler my = <kbd>new MyHandler()</kbd>;
- XMLReader xmlReader = <u>saxParser.getXMLReader</u>();
- xmlReader.<u>setContentHandler(my)</u>;
- xmlReader.parse(filename);
-}
-</code>
-
-</div>
- </body>
-</html>