Intro

J'ai créé ce blog pour partager avec vous une de mes passions : le développement informatique. J'essaierais de vous faire profiter de mes découvertes et surtout de publier régulièrement des articles. N'hésitez pas à apporter vos commentaires!

dimanche 17 avril 2011

Error #1090: XML parser failure: element is malformed

Aujourd’hui j'ai travaillé sur un mx:Tree dont le dataprovider provenait d’un élément XML. Cet élément est construit dynamiquement à l’aide de données saisies par l’utilisateur. L’exemple de code ci-dessous montre la manière de générer cet XML:
var xmlContentString:String = '<' + content.fieldName + ' id="' +
                    content.id + '" title="' + content.title + '"/>';                                                   
newNode = new XML(xmlContentString);
appendContents(newNode);
Dans cet exemple, le contenu de la variable content.title est saisi par un utilisateur via une interface spécifique, j'ai donc très rapidement été confronté à l’erreur suivante :
Error #1090: XML parser failure: element is malformed. (il existe aussi la version française de l'erreur : Error #1090: Echec de l'analyse XML : le format de l'élément est incorrect.)

Dans mon cas l’origine de cette erreur est simple, l’utilisateur a juste saisi un caractère réservé au langage XML (&’"<>). Après quelque recherche sur le net je n’ai pas réussi à trouver une fonction qui permet de convertir ces caractères spécifiques. C’est pourquoi j’ai implémenté ce petit utilitaire et maintenant tout marche nickel :

package common.util
{

    public class StringUtils
    {

        public static function escapeXMLSpecialCharacters(stringToEscape:String):String
        {
            if (stringToEscape)
            {
                stringToEscape = stringToEscape.replace(/["'&<>]/g, replaceXMLSpecialCharacter);
            }
            return stringToEscape;
        }

        public static function replaceXMLSpecialCharacter(capturedMatch:String, index:int,
                                                          str:String):String
        {
            switch (capturedMatch)
            {
                case '"':
                    capturedMatch = '&quot;';
                    break;
                case "'":
                    capturedMatch = '&apos;';
                    break;
                case '&':
                    capturedMatch = '&amp;';
                    break;
                case '<':
                    capturedMatch = '&lt;';
                    break;
                case '>':
                    capturedMatch = '&gt;';
                    break;
                default: //do nothing
            }
            return capturedMatch;
        }

        public function StringUtils()
        {
        }
    }
}
Dans le code ci-dessus, il faut remarquer 2 choses :
  1. En premier lieu le flag g à la fin du regex, ce dernier permet de signifier à la méthode String.match() de récupérer l'ensemble des éléments correspondant au pattern passé en paramètre.
  2. Le 2ème paramètre de la méthode String.replace() peut être une fonction. Contrairement à l'exemple de la doc Adobe, cette fonction peut prendre 3 arguments et non 4.

Pour finir, le code vu au début de cet article devient donc :
var xmlContentString:String = '<' + content.fieldName + ' id="' 
                    + content.id + '" title="' 
                    + StringUtils.escapeXMLSpecialCharacters(content.title) 
                    + '"/>';                
newNode = new XML(xmlContentString);
appendContents(newNode);

D'une manière générale, cette erreur est assez claire puisqu'elle indique que l'élément XML n'est pas correctement formé. Dans mon cas c'était la présence de caractères spéciaux mais cela aurait très bien pu être une balise qui n'est pas fermée. Quelqu'en soit la raison, il est utile de traiter la donnée erronée de manière textuelle afin d'identifier la cause exacte de cette erreur. Un bon coup de debugger devrait suffir ;) !

Aucun commentaire: