Question

Pour charger des fichiers XML avec un codage arbitraire, j'ai le code suivant:

Encoding encoding;
using (var reader = new XmlTextReader(filepath))
{
    reader.MoveToContent();
encoding = reader.Encoding;
}

var settings = new XmlReaderSettings { NameTable = new NameTable() };
var xmlns = new XmlNamespaceManager(settings.NameTable);
var context = new XmlParserContext(null, xmlns, "", XmlSpace.Default, 
    encoding);
using (var reader = XmlReader.Create(filepath, settings, context))
{
    return XElement.Load(reader);
}

Cela fonctionne, mais il semble un peu inefficace d’ouvrir le fichier deux fois. Existe-t-il un meilleur moyen de détecter le codage que je puisse faire:

 1. Open file
 2. Detect encoding
 3. Read XML into an XElement
 4. Close file
Était-ce utile?

La solution

Ok, j'aurais du y penser plus tôt. XmlTextReader (qui nous donne l'encodage) et XmlReader.Create (qui nous permet de spécifier l'encodage) accepte un flux. Alors, pourquoi ne pas ouvrir d’abord un FileStream puis l’utiliser à la fois avec XmlTextReader et XmlReader, comme ceci:

using (var txtreader = new FileStream(filepath, FileMode.Open))
{
    using (var xmlreader = new XmlTextReader(txtreader))
    {
        // Read in the encoding info
        xmlreader.MoveToContent();
        var encoding = xmlreader.Encoding;

        // Rewind to the beginning
        txtreader.Seek(0, SeekOrigin.Begin);

        var settings = new XmlReaderSettings { NameTable = new NameTable() };
        var xmlns = new XmlNamespaceManager(settings.NameTable);
        var context = new XmlParserContext(null, xmlns, "", XmlSpace.Default,
                 encoding);

        using (var reader = XmlReader.Create(txtreader, settings, context))
        {
            return XElement.Load(reader);
        }
    }
}

Cela fonctionne comme un charme. Lire des fichiers XML de manière indépendante de l'encodage aurait dû être plus élégant, mais au moins je m'en tire avec un seul fichier ouvert.

Autres conseils

Une autre option, assez simple, consiste à utiliser Linq to XML. La méthode Load lit automatiquement l'encodage à partir du fichier XML. Vous pouvez ensuite obtenir la valeur de l'encodeur en utilisant XDeclaration Propriété .Encoding . Un exemple de MSDN:

// Create the document
XDocument encodedDoc16 = new XDocument(
new XDeclaration("1.0", "utf-16", "yes"),
new XElement("Root", "Content")
);
encodedDoc16.Save("EncodedUtf16.xml");
Console.WriteLine("Encoding is:{0}", encodedDoc16.Declaration.Encoding);
Console.WriteLine();

// Read the document
XDocument newDoc16 = XDocument.Load("EncodedUtf16.xml");
Console.WriteLine("Encoded document:");
Console.WriteLine(File.ReadAllText("EncodedUtf16.xml"));
Console.WriteLine();
Console.WriteLine("Encoding of loaded document is:{0}", newDoc16.Declaration.Encoding);

Bien que cela puisse ne pas servir l’affiche originale, car il devrait refactoriser beaucoup de code, il est utile pour quelqu'un qui doit écrire du nouveau code pour son projet ou s’ils pensent que le refactoring en vaut la peine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top