Convertir un fichier plat en XML
Convertir un fichier plat en XML à l'aide d'une transformation XSL
Problématique
Dans les transformation XSL nous voyons souvent des convertions d'un fichier XML en d'autres format (XHTML, HTML, XML, fichiers plats, etc.). Mais rarement l'inverse. Pourtant, avec une simple transformation XSL et quelques astuces, il est possible de convertir un fichier plat en un fichier xml qui pourra, par la suite, être travaillé et transformé plus aisément.
L'avantage de disposer du fichier plat au format XML permet de le manipuler plus aisément.
Solution
Le fichier plat
Pour bien comprendre les astuces de la transformation, le plus simple est de prendre un exemple. Nous prendrons donc comme exemple de fichier plat à tranformer un fichier ics, fichier au format iCalendar. Ce fichier d'échange, utilisable par les agendas (outlook, Sunbird, iCal, etc.) est de la forme suivante :
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Paris
X-LIC-LOCATION:Europe/Paris
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20090115T203554Z
LAST-MODIFIED:20090115T203807Z
DTSTAMP:20090115T203554Z
UID:cd129492-bb73-430c-ac17-02ec6c6d8212
SUMMARY:Exploitation du jour
ATTACH:http://localhost/rapports/index.html
CATEGORIES:Problèmes
DTSTART;TZID=Europe/Paris:20090120T080000
DTEND;TZID=Europe/Paris:20090120T090000
DESCRIPTION:exploitation du jour
TRANSP:OPAQUE
END:VEVENT
BEGIN:VTODO
CREATED:20090115T203328Z
LAST-MODIFIED:20090115T203859Z
DTSTAMP:20090115T203328Z
UID:7c043fbd-18c4-4d2d-b4ed-3bac5e4e44ca
SUMMARY:suivi du traitement 025Q
STATUS:NEEDS-ACTION
ATTACH:http://localhost/rapports/liste_wkload.xml
CATEGORIES:Suivis
DTSTART;TZID=Europe/Paris:20090115T080000
DUE;TZID=Europe/Paris:20090115T180000
DESCRIPTION:surveiller le lancement de la chaîne 025Q
X-MOZ-GENERATION:1
END:VTODO
END:VCALENDAR
Bien qu'il soit un peu structuré, c'est un fichier plat.
La transformation XSL
Pour transformer ce fichier, nous utiliserons la transformation XSL réalisée par le très sympathique Tim Hare.
Application
Une transformation classique XSL s'effectue sur un document XML en source, obligatoirement. Pour transformer un fichier plat, il faut passer par une astuce qui va transformer simplement le fichier plat en un fichier qui pourra momentanément être interprété comme du XML. Pour cela, il y a deux méthodes.
Première méthode
Nous modifions le fichier plat très légèrement afin de le transformer en XML :
<?xml version="1.0"?>
<?xml-stylesheet href="ical2xml.xsl" type="text/xsl" ?>
<ical_input space="preserve">
[[[ insérez le contenu du fichier ics en entier ici ]]]
</ical_input>
ce qui va donner :
<?xml version="1.0"?>
<?xml-stylesheet href="ical2xml.xsl" type="text/xsl" ?>
<ical_input space="preserve">
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Paris
[...]
</ical_input>
Deuxième méthode
La première méthode nécessite de modifier le fichier ou d'en créer un nouveau en l'encapsulant dans du XML. La deuxième méthode est une variante de la première mais ne nécessite aucune modification de fichier. Elle est donc plus aisée à mettre en oeuvre. Il suffira juste de renommer le fichier .ics pour lui donner le nom de l'entité (ici calendar.ics).
Pour cela, nous avons notre fichier .ics, que nous nommerons pour l'occasion calendar.ics, et de l'autre notre transformation. Nous créons un troisième fichier (nommé par exemple ics.xml) qui va utiliser une entité dont la valeur sera le contenu du fichier .ics :
<?xml version="1.0" standalone="no"?>
<!DOCTYPE ical_input [<!ENTITY ics SYSTEM "calendar.ics">] >
<?xml-stylesheet href="ical2xml.xsl" type="text/xsl" ?>
<ical_input space="preserve">
&ics;
</ical_input>
Exécution de la transformation
Il ne reste plus qu'à passer le fichier dans la moulinette. Par exemple :
msxsl ics.xml ics2xml.xsl -o calendar.xml
ce qui va générer le fichier calendar.xml suivant :
<?xml version="1.0" encoding="UTF-16"?>
<iCalendar_Stream xmlns="http://www.ietf.org/rfc/rcf2445.txt">
<VCALENDAR>
<PRODID>-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN</PRODID>
<VERSION>2.0</VERSION>
<VTIMEZONE>
<TZID>Europe/Paris</TZID>
<X-LIC-LOCATION>Europe/Paris</X-LIC-LOCATION>
<DAYLIGHT>
<TZOFFSETFROM>+0100</TZOFFSETFROM>
<TZOFFSETTO>+0200</TZOFFSETTO>
<TZNAME>CEST</TZNAME>
<DTSTART>19700329T020000</DTSTART>
<RRULE>FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3</RRULE>
</DAYLIGHT>
<STANDARD>
<TZOFFSETFROM>+0200</TZOFFSETFROM>
<TZOFFSETTO>+0100</TZOFFSETTO>
<TZNAME>CET</TZNAME>
<DTSTART>19701025T030000</DTSTART>
<RRULE>FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10</RRULE>
</STANDARD>
</VTIMEZONE>
<VEVENT>
<CREATED>20090115T203554Z</CREATED>
<LAST-MODIFIED>20090115T203807Z</LAST-MODIFIED>
<DTSTAMP>20090115T203554Z</DTSTAMP>
<UID>cd129492-bb73-430c-ac17-02ec6c6d8212</UID>
<SUMMARY>Exploitation du jour</SUMMARY>
<ATTACH>http://localhost/rapports/index.html</ATTACH>
<CATEGORIES>Problèmes</CATEGORIES>
<DTSTART TZID="Europe/Paris">20090120T080000</DTSTART>
<DTEND TZID="Europe/Paris">20090120T090000</DTEND>
<DESCRIPTION>exploitation du jour</DESCRIPTION>
<TRANSP>OPAQUE</TRANSP>
</VEVENT>
<VTODO>
<CREATED>20090115T203328Z</CREATED>
<LAST-MODIFIED>20090115T203859Z</LAST-MODIFIED>
<DTSTAMP>20090115T203328Z</DTSTAMP>
<UID>7c043fbd-18c4-4d2d-b4ed-3bac5e4e44ca</UID>
<SUMMARY>suivi du traitement 025Q</SUMMARY>
<STATUS>NEEDS-ACTION</STATUS>
<ATTACH>http://localhost/rapports/liste_wkload.xml</ATTACH>
<CATEGORIES>Suivis</CATEGORIES>
<DTSTART TZID="Europe/Paris">20090115T080000</DTSTART>
<DUE TZID="Europe/Paris">20090115T180000</DUE>
<DESCRIPTION>surveiller le lancement de la chaîne 025Q</DESCRIPTION>
<X-MOZ-GENERATION>1</X-MOZ-GENERATION>
</VTODO>
</VCALENDAR>
</iCalendar_Stream>
Ce fichier xml généré est ensuite largement exploitable dans d'autres transformations…