2011-07-05 17 views
6

私はSqlXmlオブジェクトを受け取ります。を呼び出して、標準XmlReaderを取得して、私のDLLで処理できるようにします。XmlReaderからストリームを取得

アプリケーションのビジネスレイヤーでは、xmlを読み取り、ビジネスオブジェクトをインスタンス化できるXMySerializerがあります。

ただし、XMySerializer.Deserialize関数はSystem.IO.Streamを入力として受け取ります。

System.IO.StreamからSystem.Xml.XmlReaderへの質問はどうすればよいですか? 逆さまにすると...

答えて

3

ストリームを取得する方法はありません、XmlReaderが使用すると思います。回避策は、XmlReader.ReadOuterXml()を使用してXML全体を文字列として取得し、MemoryStreamに入れることです。

+0

これは、[通常はUTF8]エンコードされたXML(ほとんどの場合、1文字あたり1バイト)をデコードするオーバーヘッドがあり、各文字は2バイトです(いくつかの文字はI思う)。だから、テキストのデコーディングコストと考慮するダブルサイズのメモリフットプリントがあります。 – redcalx

1

できません。 XmlReaderは、多くの実装を持つ抽象クラスです(ストリームから読み込むものもあればストリームとは関係のないものも含みます)。ただし、このXMLリーダーのデータをSystem.IO.MemoryStreamに書き込んでから、このストリームをXMySerializer.Deserialize関数に渡すことができます。

8

実際、可能です。
BizTalkの一部であるため、誰もが使用しないライブラリが必要です。あなたが使用することができます

var xmlStream = new XmlTranslatorStream(xmlReader); 

There are 3 constructors:をBizTalkランタイムへのアクセス権を持っている場合は
、あなたはXmlReaderインスタンスからStreamインスタンスを提供するために、XmlTranslatorStreamを利用することができます。

XmlReaderからストリームを取得するための非常に多くの要件があるため、ほとんどの回答が「ここからは取得できません」という理由が分かります。助け

希望、
ジェイ

3

XmlReaderがまたはStreamによって裏打ちされてもしなくてもよいです。私はいくつかのメソッドを使って、StreamまたはTextWriterをXmlReaderにバックアップしようとしましたが、最終的にはオブジェクトを新しいストリームに書き込むのが最も簡単だと思います。受け入れられた回答が大きな文書ではうまく機能しないため、この方法をお勧めしたいと思います。これは、基本的にJayの回答のBizTalkバージョンが行うものの簡略化されたバージョンです(BizTalkは、 FileStreamまたはMemoryStreamとXMLのための他のいくつかの特別な処理を持っている)を使用してください:

public static class XmlExtensions 
{ 
    public static MemoryStream ToStream(this XmlReader reader) 
    { 
     MemoryStream ms = new MemoryStream(); 
     reader.CopyTo(ms); 
     return ms; 
    } 

    public static FileStream ToStream(this XmlReader reader, string fileName) 
    { 
     FileStream fs = new FileStream(fileName, FileMode.Create); 
     reader.CopyTo(fs); 
     return fs; 
    } 

    public static void CopyTo(this XmlReader reader, Stream s) 
    { 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.CheckCharacters = false; // don't get hung up on technically invalid XML characters 
     settings.CloseOutput = false; // leave the stream open 
     using (XmlWriter writer = XmlWriter.Create(s, settings)) 
     { 
      writer.WriteNode(reader, true); 
     } 
    } 
} 

CopyToは、しかし、あなたが好きなあなたは、ストリームのセットアップを設定することができるようになります。 ToStreamは、普通のMemoryStream(小規模なXMLファイルの場合)やFileStream(大きいものの場合)を使用したい場合に役立つ一般的なケースです。

XMySerializer.Deserialize(XmlReader reader, object graph) 

両方XmlSerializerDataContractSerializer中:あなたは本当にシリアル化の目的のためにこれをやっている場合はもちろん

、最終的には、それだけのようなあなたのシリアライゼーションクラスに過負荷を追加することは良いことですBCLはその考え方に従います...

関連する問題