Domanda

Per caricare file XML con codifica arbitraria ho il seguente codice:

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);
}

Funziona, ma sembra un po 'inefficiente aprire il file due volte. Esiste un modo migliore per rilevare la codifica in modo che io possa fare:

 1. Open file
 2. Detect encoding
 3. Read XML into an XElement
 4. Close file
È stato utile?

Soluzione

Ok, avrei dovuto pensarci prima. Sia XmlTextReader (che ci fornisce la codifica) sia XmlReader.Create (che ci consente di specificare la codifica) accetta uno Stream. Che ne dici di aprire prima un FileStream e poi usarlo con XmlTextReader e XmlReader, in questo modo:

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);
        }
    }
}

Funziona come un fascino. Leggere i file XML in modo indipendente dalla codifica avrebbe dovuto essere più elegante, ma almeno sto andando via con un solo file aperto.

Altri suggerimenti

Un'altra opzione, abbastanza semplice, è usare Linq in XML. Il metodo Load legge automaticamente la codifica dal file xml. È quindi possibile ottenere il valore dell'encoder utilizzando XDeclaration .Encoding . Un esempio da 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);

Anche se questo potrebbe non essere il server del poster originale, poiché dovrebbe refactificare un sacco di codice, è utile per qualcuno che deve scrivere un nuovo codice per il proprio progetto, o se pensa che ne valga la pena.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top