4

より多くの xml ドキュメントを生成するために XmlTextWriter クラスの同じインスタンスを再利用することは可能ですか? 私は次のようなことを意味します:

XmlTextWriter writer = new XmlTextWriter();
writer.WriteStartDocument();
writer.WriteStartElement("Message1");
writer.WriteEndElement();
writer.WriteEndDocument();

// do something with xml created
...

writer.Reset() // ?
writer.WriteStartDocument();
writer.WriteStartElement("Message2");
writer.WriteEndElement();
writer.WriteEndDocument();
// do something with xml created
...
4

3 に答える 3

2

XmlTextWriterクラス:

W3C Extensible Markup Language (XML) 1.0 および Namespaces in XML 勧告に準拠する XML データを含むストリームまたはファイルを生成する、キャッシュなしの転送専用の高速な方法を提供するライターを表します。

(私のものを強調)

このクラスは、Resetまたは同様の機能を提供せず、基になるストリームへのアクセスも提供しません。基になるストリームに自分でアクセスできる場合は、そのストリームを自分でリセットできます。

これはすべて、直接再利用できないことを意味します。

于 2011-02-07T08:23:27.547 に答える
2

簡単な答え: はい、それは可能です。

ただし、基になるストリームがファイルを指していない場合、これは達成されます。MemoryStream はその良い例です。

MemoryStream はストリームを「メモリ内」に保存するため、XmlTextWriter を使用して多数の XML ファイルを書き込み、各ドキュメントを終了した後、MemoryStream.ToArray() を実行して File.WriteAllBytes の引数として指定できます。

すべてのバイトを書き込んだ後、メモリ ストリームをクリアします。

MemoryStream.SetLength メソッドを呼び出してメモリ ストリームをクリアし、長さとして 0 を指定できます。

XmlTextWriter コンストラクターのストリーム オーバーロードについて詳しくは、こちらをご覧ください。

File.WriteAllBytes の場合:

リユース時の注意点についてXmlTextWriter

数年前、@NigelTouch はいくつかのコメントに懸念を表明しました。

私が見つけた問題は、WriteStartElement() の後など、途中で例外がスローされた場合、Writer を Flush() し、ストリームの長さを 0 に設定しても、Writer は Element の WriteState のままであるということです。次のドキュメントを開始するときは、終了 ">" で始まります (たとえば)。再利用を避ける

そして数時間前、@Mike-EEE が同じ問題に巻き込まれました。

サンプル ソリューションの作業コードを提供してください。ナイジェルが説明したのと同じ問題に直面しています

ところで、ちょっとした試行錯誤の結果、与えられたものを回復して、XmlTextWriter何度でも再利用することができました。

    using(MemoryStream stream = new MemoryStream())
    using(StreamReader streamReader = new StreamReader(stream))
    using(XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8))
    {
        writer.WriteStartDocument(true);
        writer.WriteStartElement("a");

        try 
        {
            throw new Exception();
        }
        catch 
        {
            // This line makes de magic: ending the document
            // avoids the issue mentioned by @NigelTouch
            writer.WriteEndDocument();
            writer.Flush();
            stream.SetLength(0);
        }


        writer.WriteStartDocument(true);
        writer.WriteStartElement("b");
        writer.WriteEndElement();
        writer.Flush();

        stream.Position = 0;

        Console.WriteLine(streamReader.ReadToEnd());

    }
于 2011-02-07T08:24:45.483 に答える
-1

フラッシュは、あなたが求めていることをほぼ実行すると思います。XML をビルドして取得し、フラッシュ、リンス、繰り返すだけです ;)

乾杯。

于 2011-02-07T08:23:31.863 に答える