Le stringhe Xml e quello scomodo Encoding!

L'Xml è decisamente una dei formati dati più interessanti per lo scambio di dati tra sistemi NON omogenei... definito da qualcuno un innovazione importante almeno quanto l'introduzione dell'ASCII, ed io approvo. Certo il primo impatto è stato dubbioso, mi sembrava di capirne l'importanza ma al tempo stess mi sembrava così anarchico! Poi ho capito che prima di parlare di Xml bisognerebbe parlare di Xsd e contratto di scambio tra le parti... ma questa è un'altra storia.

L'Xml andrebbe costruito tramite tecnologie e/o librerie (DOM, SAX... XmlWriter, XmlReader, XmlDocument... XmlSerializer) ben consolidate che facilitano e guidano la creazione di un Xml well-formatted. Ma quando arrivano nuove tecnologie c'è sempre qualcuno che proprio non le vuole accettare per cui le denigra e le sminuisce: "l'Xml? non è altro che una stringa con alcuni caratteri speciali da piazzare qui e la secondo una banale e superflua logica ... l'encoding è proprio una tremenda scocciatura!". Ecco che nascono quindi filosofie e filoni di pensiero alternativi per cui anche se i problemi avrebbero una facile risoluzione ecco che le parti si accordano sul formato dei dati non testuali, come se il formato non fosse già bello che definito, e decidono di HTMLEncodare qualsiasi carattere oltre i 127 ascii canonici per evitare il famigerato problema delle lettere accentate ... In realtà le specifiche xml vogliono che solo alcuni caratteri speciali siano html-encodati, vedere http://www.w3.org/TR/xml-c14n. E gli altri? Per gli altri è solo questione di encoding.

L'encoding - consiglio questa interessante lettura "LA CODIFICA DEI CARATTERI" -  non è solo un attributo da imbroccare che va messo nell'intestazione dell'xml ma deve essere corenete con l'encoding usato per _persistere_ l'xml. L'encoding lo possiamo paragonare al pennino che usiamo, per cui pennino e dichirazione devono essere coincidenti/coerenti... vi invito a fare l'interessante test che segue.

Definisco una funzione che scrive un Xml tenendo disgiunti encoding effettivo (qllo usato dal _pennino_) e encoding dicharato. La cosa è facilmente attuabile solo se NON si usano le librerie convenzionali cioè solo trattando l'xml come una banale stringa. La procedura scrive un file xml inserendo qualche carattere speciale ("è" e "€"), dopo averlo scritto lo prova a ricare con un XmlDocument. L'ultima operazione è paragonabile a quando aprite per prova il file con IE per constatare che un xml sia well-formatted . Nella fase di scrittura il writer - per suo disegno - trasformerà  in "?" tutti quei caratteri che non sono disponibili/supportati dall'encoding usato.

static void TestXmlEncoding(string fileName, System.Text.Encoding wEnc, string encoding)
{
    string path = Path.Combine("../../WorkingFolder", fileName);
    string text = string.Format(
        "<?xml version=\"1.0\" encoding=\"{0}\"?><root><valore>Il simbolo dell'euro è \"€\"</valore></root>",    
        encoding);

    using (StreamWriter w = new StreamWriter(path, false, wEnc))
    {
        w.Write(text);
        w.Flush();
        w.Close();
    }

    try
    {
        XmlDocument document = new XmlDocument();
        document.Load(path);
        Console.WriteLine("[{0}]: OK", fileName);
    }
    catch(Exception e)
    {
        Console.WriteLine("[{0}]: Failed\n{1}", fileName, e.Message);
    }
}

Facciamo ora i seguenti test ...

System.Text.Encoding iso8859_1 = System.Text.Encoding.GetEncoding("ISO-8859-1");
System.Text.Encoding win_1552 = System.Text.Encoding.GetEncoding("WINDOWS-1252");
System.Text.Encoding iso8859_15 = System.Text.Encoding.GetEncoding("ISO-8859-15");

TestXmlEncoding("good-iso8859-1.xml", iso8859_1, "ISO-8859-1"); 
TestXmlEncoding("good-iso8859-15.xml", iso8859_15, "ISO-8859-15"); //"ISO-8859-1" + "€"
TestXmlEncoding("good-windows-1252.xml", win_1552, "WINDOWS-1252");
TestXmlEncoding("good-ascii.xml", System.Text.Encoding.ASCII, "us-ascii");
TestXmlEncoding("good-utf8.xml", System.Text.Encoding.UTF8, "UTF-8");

//... qui facciamo finta che sia UTF-8 ma che tale non sarà... ;-p
TestXmlEncoding("bad-utf8-but-iso8859-1.xml", iso8859_1, "UTF-8");
TestXmlEncoding("bad-utf8-but-iso8859-15.xml", iso8859_15, "UTF-8");
TestXmlEncoding("bad-utf8-but-win1252.xml", win_1552, "UTF-8");            
TestXmlEncoding("bad-utf8-but-ascii.xml", System.Text.Encoding.ASCII, "UTF-8");

Il caricamento di "bad-utf8-but-ascii.xml" non fallisce perchè l'encoding ASCII non supporta i caratteri speciali da noi usati che quindi - come detto sopra - sono stati tutti sostituiti dal writer con comunissimi "?". Andando a sbirciare i file si potrà infatti vedere che "us-ascii" non supporta ne lettere accentate ne i simboli come "€", "iso-8859-1" non supporta il simbolo "€" introdotto da "iso-8859-15". "UTF-8" - encoding di default dei file xml se non specificato - supporta infine sia caratteri accentati sia il simbolo dell'euro.

... e che dio ci scampi da affermazioni del tipo "UTF-8 non supporta le lettere accentate!" oppure "per le lettere accentate si deve usare HTML-Encode" :-p

posted @ mercoledì 1 marzo 2006 13:22

Print

Comments on this entry:

# re: Le <em>stringhe</em> Xml e quello scomodo Encoding!

Left by luca at 01/03/2006 16:47
Gravatar
grazie,
molto interessante
Comments have been closed on this topic.
«novembre»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011