Laurent Kempé
Rédaction, Publication et Présentation de contenu crée en XML à l'aide de Word 2003, Partie 4
Présentation du système de publication de contenu mis en place sur notre site Tech Head Brothers utilisant les technologies XML de Word 2003 ainsi que
Par Laurent Kempé publié le 11/05/2004 à 22:22, lu 10939 fois, 1 pages
Introduction
Dans la partie précédente nous avons vu comment utiliser les événements et les délégués afin de pouvoir enrichir les fonctionnalités de notre document. Ce qui nous a permis de sauvegarder automatiquement le document au format XML.
Dans cet article, nous allons voir comment il est possible de faire une transformation XSLT du document et une prévisualisation de rendu comme elle serait faite sur le site, mais en déconnecté sur la machine de l'auteur.
Evénements, Délégués (bis)
Lors de la sauvegarde du document nous demandons à l'auteur si il désire avoir une prévisualisation de son article mit en forme comme il le sera sur le site. Ceci est fait dans la méthode « ThisDocument_BeforeSave » que nous avons étendu comme suit :
protected void ThisDocument_BeforeSave(Word.Document document, ref bool b, ref bool q)
{
    DialogResult result = MessageBox.Show("Do you want to save as XML also?",
                                          "Tech Head Brothers - Article", 
                                          MessageBoxButtons.YesNo);

    THBDocument thbdocument = new THBDocument(ThisDocument);

    if ( result == DialogResult.Yes)
    {
        thbdocument.Save();

        result = MessageBox.Show("Do you want to preview the article?",
        "Tech Head Brothers - Article", 
        MessageBoxButtons.YesNo);

        if ( result == DialogResult.Yes)
        {
            thbdocument.Preview();
        }
    }
Le code gérant réellement la prévisualisation est implémenté dans une classe THBDocument afin de clarifier le code dans la classe générée par le modèle.
Transformation
L'auteur désire donc sauvegarder son document et le visualiser comme il sera présenté aux lecteurs sur le site. Ce que nous avons à notre disposition pour le moment c'est un document XML bien formé et valide par rapport au schéma présenté dans un des articles précédents. La présentation ce fait sous forme HTML dans le browser. Il nous faut donc transformer ce document XML en HTML à l'aide d'une transformation XSLT.

Nous pourrions faire la transformation dans notre programme attaché au document mais nous avons opté pour une autre solution : laisser le browser faire la transformation pour nous. Ceci nous donne la flexibilité de changer la transformation et donc le document HTML à tout moment sans avoir à modifier notre programme. Pour cela il nous faut modifier le header du document XML afin de lui ajouter une référence sur notre fichier XSLT :
<?xml version="1.0" encoding="iso-8859-1" ?>
<?xml-stylesheet type='text/xsl' href='Preview_Content20.xsl' ?>
Cette modification ce passe dans la méthode Preview de notre classe THBDocument lors de la sauvegarde du document.
public void Preview()
{
	Save(XmlPreviewPath, new LocalTransformer());
La méthode Preview délègue la responsabilité de la sauvegarde à la méthode Save qui prend en paramètre une chaîne de caractères contenant le chemin où le fichier XML sera sauvegardé ainsi qu'une de transformation héritant de la classe BaseTransformer elle-même héritant de l'interface ITransformer. Nous utilisons la transformation du document XML produit par Word 2003 pour des raisons de flexibilité. Par exemple dans le document Word 2003, l'auteur référence des images ou du source sous forme de chemin sur un fichier. A la sauvegarde du document Word 2003 au format XML, le fichier contenant l'image est lu et le tag XML défini pour le document Word 2003 est transformé en un autre tag XML représentant une image avec des informations directement lu depuis le fichier comme la taille de l'image. Nous pouvons aussi ajouté du traitement. Par exemple imaginons que l'image soit trop grande en taille afin d'être affichée correctement sur le site. Il est possible à ce moment de créer automatiquement une vignette de cette image et d'afficher cette vignette dans l'article. Avec un peu de javascript en plus, il est possible de permettre aux lecteurs de cliquer sur la vignette afin d'en voir l'image originale. C'est ce genre de possibilité que nous pouvons ajouter à notre document afin de simplifier la vie aux auteurs.
Nous avons deux méthodes de transformation, une qui fait une transformation locale pour une prévisualisation sur l'ordinateur de l'auteur, car les images doivent être correctement référencées avec leur chemin. Et une autre pour le site.
La transformation est implémenté à l'aide du design pattern chaîne de responsabilité, comme présenté dans l'article suivant : Présentation du Design Pattern chaîne de responsabilité. Nous factorisons le code de transformation présent dans les deux transformation dans la classe de base BaseTransformer :
public interface ITransformer
{
    string Transform(string input, string path);
}

public class BaseTransformer : ITransformer
{
    public virtual string Transform(string input, string path)
    {
        StringBuilder sb = new StringBuilder(input);

        //TODO: Add all these settings to the application config file
        sb = sb.Replace("'","&apos;");
        sb = sb.Replace("","&apos;");
        sb = sb.Replace("","&apos;");
        sb = sb.Replace("","...");
        sb = sb.Replace("","oe");

        return sb.ToString();
    }
}
La chaîne de responsabilité est crée dans la classe LocalTransformer qui hérite de BaseTransformer :
/// <summary>
/// Transform the xml generated by Word 2003 to the format 
/// </summary>
public class LocalTransformer : BaseTransformer
{
    public override string Transform(string input, string path)
    {
        input = base.Transform(input, path);

        // Setup Chain of Responsibility

        Handler h1 = new CodeHandler();
        Handler h2 = new ImgLocalHandler();
        Handler h3 = new XmlHandler();
        Handler h4 = new ArticleHandler();
        Handler h5 = new LinkHandler();

        h1.Path = h2.Path = h3.Path = h4.Path = h5.Path = path;
        
        h1.SetSuccessor(h2);
        h2.SetSuccessor(h3);
        h3.SetSuccessor(h4);
        h4.SetSuccessor(h5);

        return h1.HandleRequest(input);
    }
}
Le but n'étant pas de parler du design pattern chaîne de responsabilité mais de l'outil de création et de publication de contenu, je vous invite à lire l'article Présentation du Design Pattern chaîne de responsabilité. Par contre il est important de voir encore comment le tag original XML du document crée par Word 2003 est remplacé. Pour cela nous utilisons les expressions régulières qui sont plus utile dans ce cas qu'une requête XPath.
class XmlHandler : Handler
{
    override public string HandleRequest(string input)
    {
        Regex regex = new Regex(@"<?xml(?<attribut>.*?)\?>", options);

        MatchEvaluator evaluator = new MatchEvaluator(Replace);

        string output = regex.Replace(input, evaluator);

        if( successor != null )
            output = successor.HandleRequest(output);

        return output;
    }

    override protected string Replace(Match m)
    {
        return "xml version=\"1.0\" encoding=\"iso-8859-1\" ?><?xml-stylesheet type='text/xsl' href='Preview_Content20.xsl' ?>";
    }
}
Transformation XSLT
Nous avons à notre disposition un fichier XML bien formé et respectant un schéma que nous avons défini. Il nous reste pour l'afficher dans un browser à transformer ce fichier XML en HTML à l'aide d'une transformation XSLT. C'est le fichier XSLT qui contient le squelette de la représentation HTML de votre site et qui va récupérer à l'aide de requête XPath des donnés dans le document XML afin de les copier dans le document HTML final. En voici une partie :
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="html" version="4.0" encoding="iso-8859-1" indent="yes" />

   <xsl:template match="article">
	<HTML>
	<HEAD>
	<title>
	Tech Head Brothers
	</title>
	  
	</HEAD>
	<body leftmargin="0" bottommargin="0" rightmargin="0" topmargin="0" marginheight="0" marginwidth="0">

      <table cellspacing="0" cellpadding="0" border="0" width="1024" align="center">
         <tr valign="top">
            <td align="left">
               <table cellspacing="1" cellpadding="1" border="0" width="100%" class="articleDescription">
                  <tr valign="top">
                     <td align="center" valign="center">
                     </td>

                     <td align="left">
                     <b>
                       <xsl:value-of select='title' />
                     </b>

                     par 
                     <xsl:choose>
                        <xsl:when test="string-length(author/email)=0">
                           <xsl:value-of select='author/name' />
                        </xsl:when>

                        <xsl:otherwise>
                           <a target="_self" href='mailto:{author/email}'>
                              <xsl:value-of select='author/name' />
                           </a>
                        </xsl:otherwise>
                     </xsl:choose>
                     <br />

                     <br />

                     <xsl:value-of select='description' />.
                     </td>

                  </tr>
               </table>

               <xsl:apply-templates select="content" />
            </td>
         </tr>
      </table>

	</body>
	</HTML>
   </xsl:template>
   
   ...
   
</xsl:stylesheet>

Affichage
Il ne nous reste plus qu'à afficher le document à l'aide d'Internet Explorer afin que l'auteur puisse valider son article par rapport à l'aspect visuel sur le site. Pour cela nous utilisons l'astuce suivante : Comment lancer un processus afin de terminé d'écrire la méthode Preview de notre classe THBDocument :
public void Preview()
{
    Save(XmlPreviewPath, new LocalTransformer());

    //Preview
    Process proc = new Process();
    //On spcifie les valeurs utiliser pour dmarrer le processus
    ProcessStartInfo processStarInf = new ProcessStartInfo();
    //on dsire lancer Internet Explorer
    processStarInf.FileName = "iexplore.exe";
    //on lui passe en argument une url
    processStarInf.Arguments = "file://" + XmlPreviewPath;
    //spcifie la taille de la nouvelle fenetre au dmarrage du processus
    processStarInf.WindowStyle = ProcessWindowStyle.Maximized;
    // Dmarre le processus
    proc = Process.Start(processStarInf);
}
Conclusion
Nous avons vu dans cette partie de notre série d'articles comment transformer le document XML produit par Word 2003 afin d'y ajouter des fonctionnalités plus difficile à obtenir directement depuis Word 2003 lui-même. Nous vous avons aussi montré comment utiliser la puissance du XML, XSLT et XPath afin d'avoir une solution flexible de présentation de contenu.

Cette solution est vraiment une solution qui nous donne une très grande facilité dans notre travail de rédaction. Merci à Word 2003 et à notre outil ;-). Elle nous permet aussi de changer la charte graphique du site en très peu de temps ainsi que de rajouter des types de média au système sur lesquels sont présenté le contenu. Merci à XML, XSLT. Je vous recommande si vous avez à produire des documents de regarder dans cette direction car même si il faut investir du temps dans la création d'une telle solution ce temps est largement rentabilisé lors de changements à effectuer dans les documents.

Nous verrons dans le prochain article de la série comment les auteurs me font parvenir leurs articles sous forme de zip directement depuis Word 2003.
 
» Démarrer une discussion