2009-03-12 11 views
7

Aşağıdaki kod var keyfi kodlamasıyla XML dosyalarını yüklemek için: Bu işlerXML dosyasında kodlamayı en iyi nasıl tespit edebilirim?

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

, ancak iki kez dosyayı açmak için biraz verimsiz görünmektedir.

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

cevap

8

Tamam, bu daha önce düşünmüş olmalıdır: Yapabileceğim şekilde kodlamayı tespit etmek için daha iyi bir yolu var mı. Hem XmlTextReader (bize Kodlama verir) hem de XmlReader.Create (kodlamayı belirtmemizi sağlar) bir Akışı kabul eder. Peki ilk önce bu gibi XmlTextReader ve XmlReader hem bu kullanmak sonra FileStream açma ve yaklaşık:

Bu bir cazibe gibi çalışır
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 dosyalarını bir kodlamada bağımsız bir şekilde okumak daha zarif olmalıydı, ama en azından bir dosya açıp kapamaya başladım.

+0

[XmlReaderCreate (Akışı)] 'nın (http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.create.aspx) aşırı yüklenmesini çağırmak, aynı şekilde kodlama? –

+0

@petrk. - Ben 'Encoding' özelliği sağlayan sınıf beri XmlTextReader açıkça kullanıyorum. Aklında başka ne olduğundan emin değil misiniz? –

+0

Doğru, açıklamama izin ver. Görünüşe göre XElement.Load (XmlReader.Create (yeni FileStream (dosya yolu, FileMode.Open))) 'ın bazı şeyleri yapması gerekiyor (kısırlık için atılan kaynakları bertaraf etmek). [XmlReader.Create (Stream)] için belgeler (http://msdn.microsoft.com/en-us/library/756wd7zs.aspx) diyor ki: _XmlReader, bayt sırası işareti arayan akışın ilk baytını tarar veya diğer kodlama işareti. Kodlama belirlendiğinde, kodlama akışı okumaya devam etmek için kullanılır ve işlem girişi (Unicode) karakter akışı olarak ayrıştırmaya devam eder. Eğer açık –

0

Diğer bir seçenek, oldukça basit, Linq to XML'i kullanmaktır. Load yöntemi, kodlamayı otomatik olarak xml dosyasından okur. Daha sonra kodlayıcı değerini XDeclaration.Encoding özelliğini kullanarak alabilirsiniz. MSDN'den bir örnek:

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

bu o kod çok refactor olurdu olarak değil sunucu orijinal afişi, may da, eğer kendi proje için yeni kod yazmak zorunda, ya da birisi için yararlıdır Onlar refactoring buna değer olduğunu düşünüyorum.

İlgili konular