X-Git-Url: http://git.nguyen.vg/gitweb/?a=blobdiff_plain;f=xpi%2Fxpi_07.xhtml;fp=xpi%2Fxpi_07.xhtml;h=30ef14e0cfb5494282d6d780ca8c77d1b66c461a;hb=55937b25bd7d4b822dabd3991d9aeed1d6ffaccc;hp=0000000000000000000000000000000000000000;hpb=ee6c766f999c190866455e8e3eae6240c7640d55;p=hacks%2FsimpleWebSlides.git diff --git a/xpi/xpi_07.xhtml b/xpi/xpi_07.xhtml new file mode 100644 index 0000000..30ef14e --- /dev/null +++ b/xpi/xpi_07.xhtml @@ -0,0 +1,433 @@ + + + +
+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 javax.xml.xpath. Comme pour le reste + de JAXP, on passe par un XPathFactory pour créer une + nouvelle instance du moteur XPath. +
+ //Pour les documents et DOM
+ import org.w3c.dom.*;
+ import javax.xml.namespace.QName;
+ import javax.xml.parsers.DocumentBuilder;
+ import javax.xml.parsers.DocumentBuilderFactory;
+
+ //Pour le moteur XPath
+ import javax.xml.xpath.XPathFactory;
+ import javax.xml.xpath.XPath;
+ import javax.xml.xpath.XPathConstants;
+
+ public class TestXPath {
+ //Deux attributs pour contenir le moteur XPath et le document builder
+ XPath xp_ = null;
+ DocumentBuilder db_ = null;
+
+
+ public TestXPath () {
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+ db_ = factory.newDocumentBuilder();
+
+ XPathFactory xf = XPathFactory.newInstance();
+ xp_ = xf.newXPath();
+
+ } catch (Exception e) {
+ //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.
+ }
+ }
+
+
+
+ NodeList eval(String fichier, String chemin) throws Exception {
+
+ //Création d'un DOM pour le fichier source
+ Document doc = db_.parse(fichier);
+
+ NodeList nl = (NodeList) xp_.evaluate(chemin,
+ doc,
+ XPathConstants.NODESET);
+
+
+ }
+
+
+La méthode XPath.evaluate(xpath, n, type) permet d'évaluer une
+ l'expression xpath (donnée sous-forme de chaîne de
+ caractères), à partir du nÅud contexte n (qui doit
+ implémenter l'interface Node). Le résultat est de
+ type typ. La fonction renvoie un résultat de
+ type Object. L'argument typ peut avoir 5 valeurs
+ possibles, définies dans la class XPathConstants :
+
En effet, une expression XPath peut avoir comme valeur un booléen,
+ un ensemble de noeuds ou une chaîne dépendant du contexte où
+ elle est utilisée. On peut demander à Jaxp d'évaluer la requête
+ XPath pour un certain contexte.
+
Document doc = ...
+ String chemin = "//descendant::year[position () = 1]";
+
+
+ //Crée une NodeList à un élément
+ NodeList nl = (NodeList) xp_.evaluate(chemin, doc, XPathConstants.NODESET);
+
+ //Renvoie le nÅud correspondant ou null
+ Node n = (Node) xp_.evaluate(chemin, doc, XPathConstants.NODE);
+
+ //Renvoie le double java correspondant à la valeur
+ Double d = (Double) xp_.evaluate(chemin, doc, XPathConstants.NUMBER);
+
+ //Renvoie la chaine java correspondant au texte
+ String s = (String) xp_.evaluate(chemin, doc, XPathConstants.STRING);
+
+ //Renvoie la valeur de vérité corresondant au chemin
+ Boolean b = (Boolean) xp_.evaluate(chemin, doc, XPathConstants.BOOLEAN);
+
+Cette classe est similaire à l'utilisation
+ de PreparedStatements en JDBC.
+Utilité ?
+compiler la requête XPath une fois pour toute
+ et donc éviter de re-parser la chaîne de caractère à chaque
+ appel.
Exemple :
+
+ XPathExpression ex = xp_.compile("//movie/title");
+
+ NodeList nl1 = (NodeList) ex.evaluate(doc1, XPathConstants.NODESET);
+ NodeList nl2 = (NodeList) ex.evaluate(doc2, XPathConstants.NODESET);
+ NodeList nl3 = (NodeList) ex.evaluate(doc3, XPathConstants.NODESET);
+ â¦
+
+
+Appliquer une transformation XSLT est une opération complexe à + cause des différentes combinaisons possibles : +
+On a donc une série de classes d'encapsulation (Source, + â¦), de factory, â¦
+Pour créer une transformation XSLT, il faut les classes suivantes, + du package: javax.xml.transform
+
+ //La classe permettant d'appliquer une transformation XSLT
+ //ainsi que sa factory
+ import javax.xml.transform.Transformer;
+ import javax.xml.transform.TransformerFactory;
+
+ //La classe permettant de charger des transformations ou des
+ //arguments de transformation sous forme de fichiers
+ import javax.xml.transform.stream.StreamSource;
+
+ //La classe permettant de charger des documents ou transformations
+ //sous forme de nÅuds DOM
+ import javax.xml.transform.dom.DOMSource;
+
+
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ //On crée un StreamSource à partir d'un nom de fichier contenant
+ //la feuille de style XSLT
+ Transformer tr = tf.newTransformer(new StreamSource("style.xsl"));
+
+
+Le code ci-dessus crée un objet de type Transformer
+ représentant la transformation XSLT se trouvant dans le fichier
+ style.xsl.
+ Si on avait chargé le fichier sous forme d'un
+ arbre DOM:
+
Document style_xsl = ⦠;//chargement de style.xsl
+
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer tr = tf.newTransformer(new DOMSource(style_xsl));
+
+
+
+ transform(Source xmlSource, Result outputTarget)
+
+Les interfaces Source et Result permettent + d'abstraire le type de l'entrée et de la sortie. Ces dernières + peuvent être :
+
+ //On applique le transformer associé à style.xsl
+ //sur le fichier movie et on écrit le résultat sur
+ //la sortie standard :
+
+ tr.transform(new StreamSource("movies.xml"), new StreamResult(System.out));
+
+La manière la plus simple de sérialiser un document 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)
+
+ Document doc = â¦; //l'objet DOM que l'on veut sauver dans un fichier
+ Transformer tr = tf.newTransformer();
+ tr.transform(doc, new StreamSource(new FileOutputStream("fichier.xml")));
+
+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 : +
+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 : +
+
+import javax.xml.parsers.*;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+On doit étendre la classe par DefaultHandler
+
+ //le parseur a lu length caractères qui se trouvent dans
+ //ch à partir de la position start
+ void characters(char[] ch, int start, int length)
+
+ //le parseur a détécté la fin de document
+ void endDocument()
+
+ //le parseur a détecté la fin d'un élément
+ void endElement(String uri, String localName, String qName)
+
+ //le parseur a détecté du texte « ignorable »
+ void ignorableWhitespace(char[] ch, int start, int length)
+
+ //le parseur a détecté le début du document
+ void startDocument()
+ //le parseur a detecté le début d'un élément
+ void startElement(String uri,String localName, String qName,
+ Attributes attributes)
+
+Attributes est une classe auxiliaire qui permet de + connaître le nom, le nombre et les valeurs des attributs pour cette + balise.
+On étend la classe DefaultHandler :
+
+class MyHandler extends DefaultHandler {
+ private int nb_elems;
+ MyHandler() {
+ nb_elems = 0;
+ }
+ void startElement(String uri,String localName, String qName,
+ Attributes attributes)
+ throws SAXException {
+ nb_elems++;
+
+ }
+ int getNbElems() { return nb_elems; };
+}
+
+
+
+On utilise (encore) une factory :
+
+ public static void main(String[] args) {
+ â¦
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setNamespaceAware(true);
+ SAXParser saxParser = spf.newSAXParser();
+
+ MyHandler my = new MyHandler();
+ XMLReader xmlReader = saxParser.getXMLReader();
+ xmlReader.setContentHandler(my);
+ xmlReader.parse(filename);
+}
+
+
+