2009-03-12 9 views
7

は、私は次のコードを持っている任意のエンコーディングでXMLファイルをロードするには:これは動作します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 

答えて

8

[OK]を私はこれを以前考えていたはずです。 XmlTextReader(エンコーディングを与える)とXmlReader.Create(エンコーディングを指定できる)の両方がStreamを受け入れます。それでは、どの最初にこのように、XmlTextReaderクラスおよびXmlReaderの両方でこれを使用し、その後のFileStreamを開き、およそ:

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ファイルを読むことは、よりエレガントであったはずですが、少なくとも私は1つのファイルだけを開いています。

+0

[XmlReaderCreate(Stream)](http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.create.aspx)オーバーロードを呼び出すだけで、同じエンコーディング? –

+0

@petrk。 - XmlTextReaderは明示的に 'Encoding'プロパティを提供するクラスで使用しています。他に何を念頭に置いていたのか分かりません。 –

+0

さて、私に説明させてください。 'XElement.Load(XmlReader.Create(new FileStream(filepath、FileMode.Open)))'はいくつかのことを行うべきであると思われます(簡潔にするためにリソースを省略しています)。 [XmlReader.Create(Stream)](http://msdn.microsoft.com/en-us/library/756wd7zs.aspx)のドキュメントには、次のように書かれています。_ XmlReaderは、ストリームの最初のバイトをスキャンしてバイトオーダーマークを探します。エンコーディングの他の符号。エンコードが決定されると、エンコードがストリームの読み取りを続行するために使用され、入力が(Unicode)文字のストリームとして解析され続けます。エンコードの検出 –

0

もう一つのオプションは、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); 

これは、サーバーのオリジナルポスターをないかもしれないが、彼は多くのコードをリファクタリングしなければならないとして、それは彼らのプロジェクトのために新しいコードを書くために持っている人のために有用である場合、またはリファクタリングがそれに値すると思っています。

関連する問題