Afficher des informations sur un fichier XML
XML Parser
Dans cet exercice, on va parcourir un fichier XML et puis afficher dans la console les différentes informations présentes dans ce fichier.
L'affichage dans la console doit ressembler à l'exemple ci-dessous.
Debut de l'analyse du document
Ouverture de la balise : [Nom de la balise]
--------- Traitement du namespace : [URI du Namespace] dont le prefix est : [Prefix] --------
Ouverture de la balise : [Nom de la balise ]
appartenant au namespace : [URI du namespace]
Attributs :
- Attribut [Clée de l'attribut] = [Valeur de l'attribut ]
--------------------- Fin de traitement du namespace : [Prefix] ------------------
Fermeture de la balise : [Nom de la balise]
Fin de l'analyse du document
Question
Téléchargez cette archive contenant une version incomplète de la solution, puis ouvrez la avec Eclipse.
Vous trouverez les fichiers nécessaires dans le dossier Ressource.
Question
Remplissez les interfaces nécessaires pour avoir l'affichage souhaité dans la console.
Pour les attributs, utilisez les méthodes getLocalName() et getValue() de l'instance attributs.
Pour la gestion des namespace, vous pouvez utiliser la feature qui est dédié pour cela.
reader.setFeature("http://xml.org/sax/features/namespaces", true);
reader.setFeature("http://xml.org/sax/features/namespace-prefixes",true);
Assurez vous que la feature validation est activée.
reader.setFeature("http://xml.org/sax/features/validation", true);
Il faut aussi implémenter l'interface ErrorHandler pour afficher toutes les types d'erreur possible.
ContentHandler
public class myContentHandler implements ContentHandler {
private Locator locator;
public myContentHandler()
{
super();
locator = new LocatorImpl();
}
/**
* Definir le locator.
*/
public void setDocumentLocator(Locator value) {
locator= value;
}
/**
* Evenement recu au debut de l'analyse du document XML
*/
public void startDocument() throws SAXException {
System.out.println("Debut de l'analyse du document");
}
/**
* Evenement recu a la fin de l'analyse du document XML
*/
public void endDocument() throws SAXException {
System.out.println("Fin de l'analyse du document" );
}
/**
* Evenement recu au debut du mapping sur un namespace
* @param prefix le nom du préfixe choisi.
* @param URI le lien du namespace
*/
public void startPrefixMapping(String prefix, String URI) throws SAXException {
System.out.print("----------------------------- ");
System.out.print("Traitement du namespace : " + URI + " dont le prefix est : " + prefix);
System.out.println(" -----------------------------");
}
/**
* Evenement recu a la fin du mapping sur un namespace
* @param prefix le nom du préfixe choisi.
*/
public void endPrefixMapping(String prefix) throws SAXException {
System.out.print("--------------------- ");
System.out.print("Fin de traitement du namespace : " + prefix);
System.out.println(" ------------------");
}
/**
* Evenement recu a chaque fois que l'analyseur rencontre une balise XML ouvrante.
* @param nameSpaceURI l'URL de l'espace de nommage.
* @param localName le nom local de la balise.
* @param rawName nom de la balise en version 1.0 <code>nameSpaceURI + ":" + localName</code>
*/
public void startElement(String nameSpaceURI, String localName, String rawName, Attributes attributs) throws SAXException {
System.out.println("Ouverture de la balise : " + localName);
if ( ! "".equals(nameSpaceURI)) {
System.out.println(" appartenant au namespace : " + nameSpaceURI);
}
if(attributs.getLength()!=0)
System.out.println(" Attributs : ");
for (int index = 0; index < attributs.getLength(); index++) {
System.out.println(" - Attribut "+ (index+1) + attributs.getLocalName(index) + " = " + attributs.getValue(index));
}
}
/**
* Evenement recu a chaque fois que l'analyseur rencontre une balise XML ouvrante.
* @param nameSpaceURI l'URL de l'espace de nommage.
* @param localName le nom local de la balise.
* @param rawName nom de la balise en version 1.0 <code>nameSpaceURI + ":" + localName</code>
*/
public void endElement(String nameSpaceURI, String localName, String rawName) throws SAXException {
System.out.print("Fermeture de la balise : " + localName);
if ( ! "".equals(nameSpaceURI)) { // name space non null
System.out.print(" appartenant a l'espace de nommage : " + localName);
}
System.out.println();
}
/**
* @param ch les caracteres qui sont dans un élément.
* @param start le rang du premier caractere a traiter .
* @param length la taille de la chaine a traiter.
*/
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("Texte : " + new String(ch, start, length));
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
System.out.println("Espace inutile : " + new String(ch, start, length));
}
public void processingInstruction(String target, String data) throws SAXException {
throw new UnsupportedOperationException("Not supported yet.");
}
public void skippedEntity(String string) throws SAXException {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Complément : ErrorHandler
public class myErrorHandler implements ErrorHandler{
public void warning(SAXParseException SaxException) throws SAXException {
System.out.println("Warning : "+SaxException.getMessage());
}
public void error(SAXParseException SaxException) throws SAXException {
System.out.println("Non fatal error : "+SaxException.getMessage());
}
public void fatalError(SAXParseException SaxException) throws SAXException {
System.out.println("Fatal error : "+SaxException.getMessage());
}
}
Complément : mySAXReader
public mySAXReader(String uri) throws SAXException, IOException, ParserConfigurationException
{
XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
reader.setFeature("http://xml.org/sax/features/validation", true);
reader.setFeature("http://xml.org/sax/features/namespaces", true);
reader.setFeature("http://xml.org/sax/features/namespace-prefixes",true);
reader.setContentHandler(new myContentHandler());
reader.setErrorHandler(new myErrorHandler());
reader.parse(new InputSource(uri));
}
Question
Dans cette question, vous serez invitées à garder vos Handler déjà faits pour la question précédente.
On va analyser de la même façon un autre fichier XML. Pour cela, vous allez ouvrir le fichier file2.xml dans votre fonction main.
L'analyse se traite bien ? Si non, expliquez pourquoi et trouvez une solution sans modifié le fichier file2.xml.
Utilisez les EntityResolver pour changer la DTD utilisé.
Fondamental : Explication
Le problème provient du fichier DTD qui est référencé dans le XML. En effet, le XML rajoute une balise qui n'est pas déclarée dans la DTD.
Pour résoudre ce problème, on peut utiliser un autre fichier DTD qui est plus conforme avec le XML. Pour cela on doit utiliser l'interface EntityResolver.
Le code source à introduire :
Dans la classe mySAXReader :
reader.setFeature("http://xml.org/sax/features/validation", true);
reader.setEntityResolver(new myEntityResolver());
Dans la classe myEntityResolver
public InputSource resolveEntity(String publicID, String systemID) throws SAXException, IOException {
System.out.println("Resolve entity : public ID : "+publicID+" SystemID : "+systemID);
return new InputSource("fileCorrect.dtd");
}
Complément :
Cela reste un cas très simple et basique.
Souvent cette classe est utile quand on a des références avec des PublicID, et qu'on souhaite au lieu de ça utiliser des ressources local avec SystemID.
Exemple : on référence un schéma qui est publié sur internet, mais on n'a pas accès à internet, donc on souhaite utilisez un schéma local. Dans ce cas on appelle la classe EntityResolver qui envoie le bon fichier à utiliser.
La solution complète :
Téléchargez cette archive contenant une version complète de la solution