Le Touilleur Express

  • Accueil
  • A propos de l’auteur
  • A propos du Touilleur Express

Traitement du XML en Groovy

14 février, 2010


Groovy est un langage particulièrement adapté lorsqu’il s’agit de traiter des fichiers plats. Pour rédiger le 500ème billet du blog, j’ai exporté au format WXR (WordPress eXtended RSS) l’ensemble des billets. Cela donne un gros fichier XML de 75 762 lignes que vous pouvez télécharger ici.

Lire un fichier XML avec Groovy

Pour ouvrir et lire un fichier XML avec Groovy, rien de plus simple. Il existe 2 classes principales : XmlSlurper et XmlParser. Aujourd’hui nous ne verrons que le premier.
La structure du fichier XML utilise le format WXR (WordPress eXtended RSS format). J’ai dû adapter et corriger quelques coquilles pour que le fichier puisse être parsé correctement.

Voyons tout d’abord comment lire un fichier XML en Groovy :

def file = new File("wordpress.2010-02-14.xml")
def root=new XmlSlurper().parse(file)

Plutôt simple non ?

Si nous prenons cette structure XML par exemple :

<rss version="2.0"
	xmlns:excerpt="http://wordpress.org/export/1.0/excerpt/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:wp="http://wordpress.org/export/1.0/"
>

<channel>
	<title>Le Touilleur Express</title>
        ...
        <item>
            // un article
        </item>
        <item>
            // un article
        </item>
</channel>
</rss>

L’accès à un attribut est très simple en Groovy. Voici comment afficher le titre du blog et comment afficher le nombre d’items de la balise channel:

def file = new File("wordpress.2010-02-14.xml")
def root=new XmlSlurper().parse(file)

println "Blog title : "+root.channel['title']

println "Number of RSS items : "+root.channel.item.size()

nicolas@localhosr> groovy readXml.groovy
Blog title : Le Touilleur Express
Number of RSS items : 805

Itérer des noeuds

L’itération des noeuds XML s’effectue à l’aide de closure. La structure RSS de l’ensemble des articles est construite autour du noeud « item ». WordPress y ajoute un ensemble d’attributs, ce qui permet de distinguer les articles publiés des brouillons, de distinguer les images téléchargées des pages, etc.

Prenons cet exemple de code :

def file = new File("wordpress.2010-02-14.xml")
def root=new XmlSlurper().parse(file)

root.channel.item.each{it->
	if(it.post_type.text().equals("post")){
		if(it.status.text().equals("publish")){
			println (it.title.text(),"UTF-8")
		}
	}
}

L’élément CHANNEL est constitué d’une collection d’ITEM. Pour chacun de ces ITEMs je récupere la valeur de l’attribut TITLE. Enfin l’accesseur text() permet de récupérer le titre de l’article du Touilleur Express.
Le format d’entrée est UTF-8. Lors de l’exécution sur Mac, l’encoding de la plateforme étant par défaut MacRoman, les caractères accentués entre autre ne sont pas correctement affichés. Nous verrons tout à l’heure comment spécifier le format de sortie.

Générer un nouveau fichier au format HTML

Maintenant que vous savez lire un fichier XML, itérer des noeuds, pouvez-vous m’écrire quelques lignes pour générer une page HTML avec la liste des articles, un lien vers l’article et la date de publication ?

Voici le fichier d’entrée :

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:excerpt="http://wordpress.org/export/1.0/excerpt/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:wp="http://wordpress.org/export/1.0/"
>

<channel>
	<title>Le Touilleur Express</title>
		<item>
			<title>Article classique</title>
			<wp:post_type>post</wp:post_type>
			<wp:status>publish</wp:status>
			<link>http://www.touilleur-express.fr/2003/11/22/pourquoi-java-sappelle-java/</link>
			<pubDate>Sat, 22 Nov 2003 09:28:40 +0000</pubDate>
		</item>
		<item>
			<title>Article de brouillon</title>
			<wp:post_type>post</wp:post_type>
			<wp:status>draft</wp:status>
			<link>http://www.touilleur-express.fr/</link>
			<pubDate>Sat, 22 Nov 2003 09:28:40 +0000</pubDate>
		</item>
		<item>
			<title>Page wordpress</title>
			<wp:post_type>page</wp:post_type>
			<wp:status>publish</wp:status>
			<link>http://www.touilleur-express.fr/</link>
			<pubDate>Sat, 22 Nov 2003 09:28:40 +0000</pubDate>
		</item>
	</channel>
</rss>

Votre script Groovy doit parser le fichier XML ci-dessus, et générer ce fichier HTML :

<html>
<head>
<title>Le Touilleur Express articles</title>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>

<body>
<a href='http://www.touilleur-express.fr/2003/11/22/pourquoi-java-sappelle-java/' target='new'>Article classique</a> publié le Sat, 22 Nov 2003 09:28:40 +0000<br/>

</body>
</html>

Allez au boulot, à vous de travailler. Je vous posterai la réponse un peu plus tard.

Articles similaires:

Default ThumbnailGroovy Default ThumbnailLA grosse nouvelle : SpringSource rachète G2One Groovy Default ThumbnailIntroduction à Spring Integration Default ThumbnailComment lister le contenu d'un fichier jar ?
  • Raphael brugier 14 février 2010 at 20 h 12 min

    Woops, ça ne le fait pas du tout les balises html dans les commentaires 🙁

    Désolé pour le spam, j’essaye de reposter en échappant les balises :

    Salut !

    Je débute en groovy, mais voilà comment j’aurais fait :
    (mais il y a surement plus groovy …)

    
    def file = new File("/home/raf/test.xml")
    def root=new XmlSlurper().parse(file)
    
    def title = root.channel['title']
    
    println "<html>"
    println "<head>"
    println "<title> $title articles </title>"
    println "<meta  http-equiv='Content-Type' content='text/html; charset=UTF-8'/>\n"
    println "<body>"
    
    // Les articles
    root.channel.item.each{it->
        if(it.post_type.text.equals("post")){
            if(it.status.text.equals("publish")){
                href = it.link
                title = it.title
                date = it.pubDate
                println "<a href='$href' target='new'>$title</a> publié le $date</br>"
            }
        }
    }
    
    println "</body>"
    println "</html>"
    
  • Stéphane 15 février 2010 at 15 h 14 min

    C’est pas du très beau code mais cela devrait faire l’affaire (in.xml contient évidemment le xml proposé en entrée) :

    
    import groovy.xml.MarkupBuilder
    
    def file = new File("in.xml")
    def root=new XmlSlurper().parse(file)
    
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
    
    xml.html {
        head {
            title('Le Touilleur Express articles')
            meta("http-equiv":'Content-Type', content:'text/html; charset=UTF-8')
        }
        body {
            root.channel.item.each{currentItem->
                    if(currentItem.post_type.text().equals("post")){
                            if(currentItem.status.text().equals("publish")){
                                    a(href:currentItem.link.text(), target:'new', currentItem.title.text())
                                    mkp.yield(' publié le ' + currentItem.pubDate.text())
                                    br()
                            }
                    }
            }
        }
    }
    
    println writer.toString()
    
  • Nicolas Martignole 15 février 2010 at 19 h 27 min

    @Stephane ta technique est la plus groovy, celle de Raphael est légèrement plus rapide. Bravo les gars !

Derniers articles

  • Vis ma vie de Staff/Principal Engineer

    Suite de l’article précédent sur le Staff Engineer. Aujourd’hui, voyons un peu

    20 juillet, 2022
  • Inari

    Devenir Staff Engineer : comment et pourquoi ?

    Après une dizaine d’années en tant que développeur, vous serez un jour

    17 juillet, 2022
  • WeAreDevelopers 2022, conférence à Berlin – jour 1

    Il est 8h40, 19 degrés, vous êtes à Berlin. La queue dehors

    24 juin, 2022

Tweets @nmartignole

  • RT  @katecrawford : Umm, anyone a little concerned that Bard is saying its training dataset includes... Gmail? I'm assuming that's flat out…

    2 days ago
  • Je découvre qu’ils apprennent le SQL en Terminal, très intéressant https://t.co/MrfcHve9wo

    3 days ago
  • RT  @AmelieBenoit33 : Je m’essaye à de nouveaux formats ! Un premier sketch qui me trottait en tête depuis le sketchnote précédent; la techn…

    4 days ago

Mots clés

Apple (32) Architecture (13) Big Data (5) Conference (8) Devoxx (55) Dev Web (37) Doctolib (2) geekevent (1) groovy (2) Innoteria (11) Java (517) Linux (10) Non classé (14) Perso (266) Recrutement (3) Scala (30) scrum (43) Société (3) Startup (20) Web 2.0 (67)

Le Touilleur Express

Blog par Nicolas Martignole

Contactez-moi : nicolas@touilleur-express.fr

Suivez-moi sur Twitter : @nmartignole

Copyright© 2008 - 2020 Nicolas Martignole | Tous droits réservés
  • A propos de l’auteur
  • A propos du Touilleur Express
  • Log In
  • My Account
  • My Profile
  • Reset Password

Le Touilleur Express