سؤال

لتحميل ملفات 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
هل كانت مفيدة؟

المحلول

وطيب، وأرجو أن يكون فكرت في وقت سابق من هذا. كلا 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 بطريقة مستقلة ترميز كان ينبغي أن يكون أكثر أناقة ولكن على الأقل أنا الحصول على بعيدا مع ملف واحد فقط مفتوحة.

نصائح أخرى

وثمة خيار آخر، بسيط جدا، هو استخدام LINQ إلى XML. طريقة تحميل يقرأ تلقائيا الترميز من ملف 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);

ولئن كان هذا لا يجوز خادم الملصق الأصلي، كما انه يجب أن ريفاكتور الكثير من التعليمات البرمجية، فإنه من المفيد لشخص لديه لكتابة رمز جديد لمشروعهم، أو إذا كانوا يعتقدون أن إعادة بيع ديون يستحق ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top