1

XmlWriter (C#、.NET) を使用して、XML を生成するメソッドへの複数の呼び出しと、すべてを終了する最終メソッドへの 1 回の呼び出しで XML ドキュメントを作成できるようにしたいと考えています。このメソッドを複数回呼び出そうとすると:

private void SiblingGenerator(List<XmlNode> XMLList, XmlWriter textWriter,
    string newPath, FileInfo fi)
{
    if (fi.Length == 0)
    {
        MessageBox.Show("file doesn't exist");

        textWriter.WriteStartDocument();
        textWriter.WriteStartElement("batch");
        //...
    }

    // ...
}

...というエラーが返されますWriteStartDocument needs to be the first call

への呼び出しは実際には書き込まれていないように見えます。これtextWriterは、後続の呼び出しごとにドキュメントが最初からやり直すためです。

なぜこれが起こっているのか誰にも教えてもらえますか?

4

4 に答える 4

3

XmlWriter は転送専用であり、再利用できません。WriteStartDocumentこのクラスの同じインスタンスで複数回呼び出すべきではありません。これはメソッドの引数であるため、ライターのライフサイクルを処理する必要があるのは呼び出し元です。

using (var writer = XmlWriter.Create("foo.xml"))
{
    SiblingGenerator(XMLList, writer, newPath, fi);
}

関数を複数回再利用する必要がある場合は、メソッドSiblingGeneratorの呼び出しを外部化することができます。WriteStartDocument

using (var writer = XmlWriter.Create("foo.xml"))
{
    writer.WriteStartDocument();
    SiblingGenerator(XMLList, writer, newPath, fi);
    SiblingGenerator(XMLList, writer, newPath, fi);
    ...
    writer.WriteEndDocument();
}
于 2011-01-02T22:15:55.680 に答える
1

TextWriter、XmlWriter などのあらゆる種類の「ライター」オブジェクトは、完全に制御できない下層のストリームと同様に、ある程度のバッファリングを行います。つまり、基になるファイルの長さに依存して、ライターへの以前の呼び出しが行われたかどうかを判断することはできません。

しかし具体的に言えば、 Stream や TextWriter などの System.IO の多くのクラスで使用できるFlushメソッドがあり、これを使用してバッファリングされたコンテンツをディスクにプッシュできますが、私の意見では、これはかなり脆弱なコードになります。

文書の先頭をすでに書いているかどうかを判断するには、他の種類の状態を維持する必要があります。

于 2011-01-02T22:16:52.033 に答える
1

その方法が機能しない原因がいくつかあります。はXmlWriterコードをストリームに直接FileStream書き込まない場合や、データをファイルに直接書き込まない場合があり、FileInfoオブジェクトはその情報をキャッシュするため、最新の情報を取得するにはそれ自体を更新する必要があります。

オブジェクトを使用してこれを確認する代わりにFileInfo、ブール変数を使用して、それが最初の項目かどうかを追跡できます。

または、このメソッドを呼び出すループに入る前に、ドキュメントの先頭を書き込んでください。

于 2011-01-02T22:17:37.320 に答える
-1

何か他に問題があると思いますが、そのコードは機能するはずです。おそらく XmlWriter を再利用しています。メソッドでローカルに XmlWriter を宣言すると、まだエラーが発生しますか?

于 2011-01-02T22:14:00.930 に答える