Outils pour utilisateurs

Outils du site


public:swb_xml

*Page ARCHIVÉE*

Traitements de fichiers XML (objectifs de stage)

Traitements XML reproduisant ceux de la bibliothèque LML.

Objectif

  • ajouter un attribut 'A' à tout élément XML désigné par une XPath 'P' avec une valeur 'X'
    • depuis Eclipse
      • depuis le programme Java
        • ouvrir le fichier XML d'entrée (exemple 'entree.xml' dans un répertoire '/home/nchurlet')
          • un fichier XML est un fichier texte qui contient des balises
        • je transforme le XML
          • je parse le XML (interprète le texte et les balises et ça crée un arbre correspondant)
            • je manipule le DOM
          • — ou je parse et je traite le flux SAX
        • j'ouvre le fichier de sortie (exemple 'sortie.xml' dans un répertoire '/home/nchurlet')
        • je sauve/écris le XML résultat de la transformation dans le fichier
          • je parcours le DOM et j'écris en sortie son contenu
          • — ou j'ai déjà écrit dans la sortie en SAX
        • je ferme le fichier de sortie
        • je ferme le fichier d'entrée
        • je quitte
  • faire une synthèse de ce qui existe déjà dans TXM (macros, scripts)
  • faire une synthèse de ce qu'il y avait dans LML (man)
  • ajouter un attribut 'A' à tout élément XML désigné par une XPath 'P' avec une valeur 'N' qui s'incrémente ;
  • encapsuler dans des macros TXM

Méthode

  • découvrir XML
  • découvrir XPath
  • découvrir l'environnement d'exécution (ligne de commande, Eclipse, TXM)
  • découvrir Java à l'aide d'objectifs progressifs :
    1. HelloWorld OK
    2. Afficher la valeur d'une variable de type “Integer” : AfficherInteger.java OK
    3. Incrémenter 10 fois une variable de type Integer à l'aide d'une boucle : IncrementerInteger.java OK
    4. Provoquer une erreur et l'afficher : ErreurJava.javaOK
  • découvrir le traitement de fichier en Java
    1. Afficher le chemin absolu d'un fichier : CheminFichier.java Ok
    2. Vérifier l'existance d'un fichier : FichierExistant.java Ok
    3. Vérifier si un fichier peut être lu : FichierLisible.java Ok
    4. Afficher le contenu d'un fichier : LireFichier.java Ok
    5. Ecrire un message dans un fichier : EcrireFichier.java
  • découvrir le traitement de fichier XML en Java
    1. Parser un fichier XML en DOM et afficher la liste des noeuds “XXX” de l'arbre XML : ParserXMLTrouverXXX.java
    2. Parser un fichier XML en DOM et afficher la liste des noeuds d'identifiant “id” “XXX” de l'arbre XML : ParserXMLTrouverXXXByID.java
    3. DUR : Parser un fichier XML en DOM et afficher la liste des noeux de l'arbre XML : ParserXML.java
    4. DUR : Parser un fichier XML en DOM et sauvegarder l'arbre XML dans un autre fichier : ParserEtCopierXML.java
  • découvrir des exemples de corpus XML
  • concevoir les algorithmes
  • définir les tests des algorithmes
  • implémenter les algorithmes
  • tester les algorithmes
  • débugger le code
  • publier une macro
    • documenter la macro

Planning

  • jeudi soir : installé l'environnement de travail
  • vendredi soir : découvert XML, XPath. Créer un premier projet Java HelloWorld.
  • lundi soir :
    • négocié avec M. X les objectifs (voir section Méthode)
    • Programme qui affiche une variable et qui lit l'entrée Clavier
    • réels, conçu, tests correspondants
  • mardi soir : implémenté et résolu qlqs bugs, tests perso, Mr X - recette effectuée (les objectifs sont atteints)
  • mercredi : commencé de la documentation, réfléchi à la publication
  • jeudi : beta + stable (après alpha)
  • vendredi : 1/2 jour de synthèse

Jeu de macros

ForceWordIDs

paramètres :

  • inputFile (.xml)

calcul :

  • calculer textid
  • copie de XML en stax
  • dans la boucle d'événements :
    • quand on a un élément w
      • si @id alors copier dans foreignid
      • créer/mettre à jour id avec valeur forgée (texte / position)

Solution

Prototypes

État de l'art

Premier programme :

  • CONSIGNE :
    • Concevoir un programme qui retourne un entier.
      • Je vais plus loin, le programme demandera un nombre (double) puis le retournera sous la forme le “opération” de “nombre” est “ résultat.
package Helloworld.EMT.Premier;
 
import java.util.InputMismatchException;
import java.util.Scanner;
 
public class afficherInteger //ça c'est ma "class"
{
	public static void main(String args[])  //ça c'est mon "main"
	{
		System.out.println("Début du prorgamme");
 
		Scanner sc = new Scanner(System.in); //J'ai importé Scanner, il permet de lire le clavier 
		                                     //et donc de communiquer de l'utilisateur au programme
		System.out.println("Merci de saisir un nombre");
 
			double A = sc.nextDouble();
			System.out.println("la moitié du multiple par 5 de " + A + " est :"
					+ A * 5 / 2);
 
		System.out.println("Fin du prorgamme");
	}
}

Pour fignoler je rajoute un message d'erreur pour cela j'utilise la fonction “try” “catch” qui se construit autour de la fonction.

try //Try va tenter une fonction et réagir sinon
		{
			double A = sc.nextDouble();
			System.out.println("la moitié du multiple par 5 de " + A + " est :"
					+ A * 5 / 2);
		} 
		catch (InputMismatchException e) //je sais quel est le nom de l'erreur, je la fait attraper
		{
			System.out.println("Erreur : " + e);//ici la réaction à avoir.
			System.out.println("Tu ne m'as pas donné un nombre petit galopin "
					+ "ou tu as utilisé un point au lieu d'une virgule");
		}
 

Pour finir correctement mon programme il faut qu'il se relance après le message d'erreur. Je vais devoir utiliser une “boucle” voici le programme final

package Helloworld.EMT.Premier;
 
import java.util.InputMismatchException;
import java.util.Scanner;
 
public class afficherInteger //ça c'est ma "class"
{
	public static void main(String args[])  //ça c'est mon "main"
	{
		System.out.println("Début du prorgamme");
		boolean fin = false; //Je souhaite créer une boucle. Je choisi sa condition qui sera un booléen.
		while (fin == false) //Tant que fin est faux, je rentre dans la boucle, sinon j'en sors et je termine
		{
 
			Scanner sc = new Scanner(System.in); //J'ai importé Scanner, il permet de lire le clavier 
			//et donc de communiquer de l'utilisateur au programme
			System.out.println("Merci de saisir un nombre");
			try //Try va tenter une fonction et réagir sinon
			{
				double A = sc.nextDouble();
				System.out.println("la moitié du multiple par 5 de " + A + " est :"
						+ A * 5 / 2);
				fin = true; //Ici je tue la condition qui relancera la boucle. Un seul = défini; == vérifie
			} 
			catch (InputMismatchException e) //je sais quel est le nom de l'erreur, je la fait attraper
			{
				System.out.println("Erreur : " + e);//ici la réaction à avoir.
				System.out.println("Tu ne m'as pas donné un nombre petit galopin "
						+ "ou tu as utilisé un point au lieu d'une virgule");
				fin = false; //Ici je maintiens la condition pour que la boucle soit relancée. 
			}
		}
 
			System.out.println("Fin du prorgamme");
		}
	}

Par la même occasion, j'ai résolu le programme numéro 2

Version béta de donnerUnAttributEtuneValeur

package defautpackage;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Arrays;
 
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
 
/**
 * 
 * @author Nicolas Churlet
 *
 */
public class SwbXML {
 
	/**
	 * 
	 * @param args vaut FILEPATH XPATH ATTRIBUT [VALEUR]
	 * @throws FileNotFoundException
	 */
	public static void main(String[] args) throws FileNotFoundException {
		System.out.println("Arguments du programme: "+Arrays.toString(args));
		if (args.length < 3) {
			System.out.println("Pas assez d'argument pour lancer la fonction.");
			System.out.println("Utilisation : java -jar AddAttributeInXML.jar FILEPATH XPATH ATTRIBUT [VALEUR]");
			return;
		}
 
		String path = args[0]; // chemin du fichier XML à traiter. ex: /home/.../fichier.xml
		String xpath = args[1]; // XPath à appliquer au fichier XML. ex: //pop
		String nomAttributARajouter = args[2]; // nom de l'attribute qu'on va rajouter. ex: n
		String valeur = null; // paramètres, si valeur=null, alors la valeur sera un compteur.
 
		if (args.length == 4) {
			valeur = args[3];
			System.out.println("Mode : constant avec la valeur "+valeur);
		} else {
			System.out.println("Mode : incrementation");
		}
 
		//		String path = "/home/nchurlet/xml/limo.xml";
		//		String xpath = "//pop"; // paramètres
		//		String nomAttributARajouter = "n"; // paramètres
		//		String valeur = "XX"; // paramètres, si valeur=null, alors la valeur sera un compteur
 
		try {
			//			Scanner sc = new Scanner(System.in);
			//			System.out.println("Veuillez saisir un chemin absolu de fichier :");
			//			String path = sc.nextLine();
			//			System.out.println("Vous avez saisi : " + path);
 
			File f = new File(path);
			if (!testerFichier(f)) {
				System.out.println("Abandon.");
				return;
			}
 
			// Créé un Stream
			FileInputStream fileInputStream = new FileInputStream(f);
 
			// Récupère les noeuds à l'aide de l'xpath
			NodeList list = evaluer(fileInputStream, xpath);
 
			// modifie les noeuds et récupère le DOM modifié
			Document doc = modifierDOM(list, nomAttributARajouter, valeur);
 
			//Ecrire le DOM dans un autre fichier
			File outfile = new File(f.getParentFile(), "resultat-"+f.getName());
 
			// on écrit le DOM modifié dans une String
			String str = convertDomToString(doc);
 
			// on écrit la String dans le fichier de sortie
			ecrireString(str, outfile);
		} catch (TransformerException e) {
			System.out.println("Erreur lors de la convertion du DOM modifié en String : "+e);
		} catch (XPathExpressionException e) {
			System.out.println("Erreur lors de l'application de l'XPath '"+xpath +"' : "+e);
		} catch (IOException e) {
			System.out.println("Erreur lors de l'écriture du fichier résultat : "+e);
		}
	}
 
	/**
	 * Prend une chaine de caractère et l'écrit dans un fichier
	 * @param str paramètre chaine de caractère
	 * @param outfile Fichier résultat
	 * @throws IOException
	 */
	private static void ecrireString(String str, File outfile) throws IOException {
		//Ouvre le fichier argument
		FileWriter filewriter = new FileWriter(outfile);
		//Prend le string pour l'écrire dans le fichier
		filewriter.write(str);
		//Ferme le fichier
		filewriter.close();
	}
 
 
	/**
	 * Prend un fichier et vérifie qu'il existe et qu'il est lisible
	 * @param f paramètre fichier
	 * @return un boolean
	 */
	private static boolean testerFichier(File f) {
		if (!f.exists()) { // verifie l'existance du fichier
			System.out.println("Le fichier "+f.getAbsolutePath()+" n'existe pas");
			return false;
		}
 
		if (!f.canRead()) {// verifie la lisibilité du fichier
			System.out.println("Le fichier "+f.getAbsolutePath()+" n'est pas lisible (droits insuffisants).");
			return false;
		}
		return true;
	}
 
	public static String convertDomToString(Document document) throws TransformerException {
		DOMSource domSource = new DOMSource(document);
 
		StringWriter writer = new StringWriter();
		StreamResult result = new StreamResult(writer);
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer transformer = null;
 
		transformer = tf.newTransformer();
		transformer.transform(domSource, result);
 
		String stringResult = writer.toString();
		return stringResult;
	}	 
 
	/**
	 * Permet de modifier un document XML  en lui ajoutant un attribut auquel on associe une valeur (de type : attribut = valeur)
	 * @param list Paramètre liste de noeuds
	 * @param nomAttributARajouter Paramètre string chaine de caractère (le nom de l'attribut à ajouter)
	 * @param valeur Paramètre string chaine de caractère (la valeur de l'attribut à ajouter)
	 * @return DOM document
	 */
	public static Document modifierDOM(NodeList list, String nomAttributARajouter, String valeur ) {
		Document doc = null; // null pour l'instant
		//incrémentation de i avec la longueur de la liste de noeud comme limite.
		for (int i = 0 ; i < list.getLength() ; i++) 
		{ 
 
			Element n = (Element)list.item(i); //A chaque boucle on récupère  le ieme élément
			if (valeur == null) {
				//S'il n'y a pas de valeur renseignée on numérote les éléments à partir de 1 
				n.setAttribute(nomAttributARajouter, Integer.toString(i+1));
			} else {
				//Sinon on donne la valeur renseignée à l'attribut qu'on ajoute.
				n.setAttribute(nomAttributARajouter, valeur);
			}
 
			if (doc == null) 	doc = n.getOwnerDocument(); 
			//Donne le conteneur racine de l'arbre XML du noeud 'n'
		}
		return doc;
	}
 
	/**
	 * 
	 * @param stream Paramètre un fichier entrant
	 * @param expression Paramètre string chaine de caractère
	 * @return Une liste de noeuds
	 * @throws XPathExpressionException
	 */
	public static NodeList evaluer(InputStream stream, String expression) throws XPathExpressionException{
		NodeList liste = null; 
		//On initialise une liste de noeud nommée "liste"
		InputSource source = new InputSource(stream);
		//Création d'une source entrante(fichier) que l'on nomme source.
 
		XPathFactory fabrique = XPathFactory.newInstance();
		//On crée une fabrique d'XPath(XPathFactory) nommée fabrique
		XPath xpath = fabrique.newXPath();
		//On crée un Xpath nommé "xpath" à partir de de la fabrique d'XPath nommée "fabrique"
 
		//évaluation de l'expression XPath
		XPathExpression exp = xpath.compile(expression);
		//Lance une méthode super balèse pq'elle va retourner des noeuds à partir de l'expression exp
		liste = (NodeList)exp.evaluate(source,XPathConstants.NODESET);
 
		return liste;
	}
 
}
// /home/nchurlet/xml/limo.xml

Version finale

Documentation

Utilisateur

Développeur

Éléments de solution :

  • Développez.com
    • Il condense toutes les raisons de trouver une solution et ce dans 15 langages JAVA (Forum, tutos, livres, vidéos, etc.)
  • openclassrooms.com/informatique/cours/apprenez-a-programmer-en-java
    • Il ressortira volontiers dans les résultats Google. Il présente des procédures explicites, des tutos, des cours, forums, librairie, dictionnaire.
  • Traduction de “Think Java” http://penserenjava.free.fr
    • C'est un livre important sur le JAVA traduit en français à 95% pour le moment. La traduction est de qualité, mais les caractère spéciaux sont illisibles.

Recette

Documentation utilisateur

Cette class fonctionne avec 4 arguments : * Un FILEPATH * Un XPATH * Un ATTRIBUT * Une [VALEUR]

S'il y a moins de 3 arguments, la classe doit renvoyer un message d'erreur : “Pas assez d'argument pour lancer la fonction.”

S'il n'y a que les 3 premiers arguments, la classe doit renvoyer le fichier Xpath renseigné avec un attribut en plus renseigné aussi et une valeur numérotée à partir de 1

S'il y a 4 arguments, la classe fonctionne comme précédemment mais la valeur étant renseignée, elle remplace la numérotation.

Documentation développeur

Cas d'erreur

Si le fichier ne peut pas être lu la classe doit afficher un abandon.

Si le document FilePath n'est pas convertissable en string (chaine de caractère) ou que la procédure a été interrompue le message ”“Erreur lors de la conversion du DOM modifié en String : TransformerException” sera présenté à l'utilisateur.

Si le Xpath n'est pas correct ou que la procédure a été interrompue, qu'on ne peut pas créer une liste de noeud, le message “Erreur lors de l'application de l'XPath 'xpath' : XPathExpressionException” sera présenté à l'utilisateur.

Si le la chaine de caratère ne peux pas être écrite dans un fichier ou que la procédure a été interrompue, le message “Erreur lors de l'écriture du fichier résultat : IOException” sera présenté à l'utilisateur.

Protocole de test

Alpha

  • Récupérer le projet “SWB-XML” du dossier smb://ensldfs.ens-lyon.fr/services/labo_ana_corpus/Equipe/NChurlet/Livraison
  • Tester dans Eclipse

Beta

  • Récupérer les fichiers suivants dans le dossier smb://ensldfs.ens-lyon.fr/services/labo_ana_corpus/Equipe/NChurlet/Livraison
    • AddAttributeInXML.jar
    • limo.xml
  • Ouvrir un terminal
    • Linux : Ouvrir le gestionanire d'application et lancer l'application “Terminal”
    • Windows : Ouvrir le menu Démarrer, sélectionner “Éxécuter…”, taper “cmd” puis “Entrée”
    • Mac : …
  • Éxecuter la commande :
    cd <dossier de téléchargement des fichiers ci-dessus>
    java -jar AddAttributeInXML.jar limo.xml //pop n XX
  • Vérifier que les balises “pop” du fichier “resultat-limo.xml” ont bien un attribut “n” avec la valeur “XX”
  • Éxecuter la commande :
    cd <dossier de téléchargement des fichiers ci-dessus>
    java -jar AddAttributeInXML.jar limo.xml //pop n
  • Vérifier que les balises “pop” du fichier “resultat-limo.xml” ont bien un attribut “n” allant de 1 à 2 (il y a 2 balises “pop”)
  • Éxecuter la commande :
    cd <dossier de téléchargement des fichiers ci-dessus>
    java -jar AddAttributeInXML.jar jexistepas.xml //pop n
  • Vérifier que le message
    Le fichier .../jexistepas.xml n'existe pas

    s'affiche

  • Fin

MD (25/07/2014) : Vérifié sur ma machine Ubuntu 12.04, OK

STABLE

  • Télécharger la macro “AddAttributeInXML” : Lien direct de téléchargement
  • Copier la macro dans le dossier : $HOME/TXM/scripts/macro
  • Lancer TXM
  • Ouvrir la vue “Macro” (si la vue est déjà ouverte cliquer sur le bouton rafraîchir)
  • Lancer la macro “AddAttributeInXML” avec un double clic. Remplir les champs :
    • xmlFile : chemin vers le fichier XML à traiter
    • xpath : la XPath qui cible les éléments à enrichir
    • nomAttributARajouter : le nom de l'attribut qui sera ajouté
    • valeur : la valeur à ajouter, si absente un compteur sera utilisé

État courant

Qui Quand Quoi

public/swb_xml.txt · Dernière modification : 28/05/2018 16:01 de matthieu.decorde@ens-lyon.fr