Как лучше всего определить кодировку в файле XML? - PullRequest
7 голосов
/ 12 марта 2009

Для загрузки файлов XML с произвольной кодировкой у меня есть следующий код:

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

Это работает, но кажется немного неэффективным, чтобы открыть файл дважды. Есть ли лучший способ определить кодировку, чтобы я мог сделать:

 1. Open file
 2. Detect encoding
 3. Read XML into an XElement
 4. Close file

Ответы [ 2 ]

8 голосов
/ 12 марта 2009

Хорошо, я должен был подумать об этом раньше. И XmlTextReader (который дает нам кодировку), и XmlReader.Create (который позволяет нам указать кодировку) принимают поток. Итак, как насчет того, чтобы сначала открыть FileStream, а затем использовать его вместе с XmlTextReader и XmlReader, например:

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

Это работает как шарм. Чтение файлов XML независимым от кодировки способом должно быть более элегантным, но, по крайней мере, я открываю только один открытый файл.

0 голосов
/ 16 апреля 2016

Еще один довольно простой вариант - использовать Linq to XML. Метод Load автоматически читает кодировку из файла xml. Затем вы можете получить значение кодера с помощью свойства XDeclaration.Encoding . Пример из 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);

Несмотря на то, что это может не обслуживать оригинальный постер, поскольку ему придется рефакторинг большого количества кода, это полезно для тех, кому нужно написать новый код для своего проекта, или если они считают, что рефакторинг того стоит. *

...