使用XmlWriter迭代构建XML文件

时间:2011-01-02 22:09:48

标签: c# .net xml xmlwriter

我希望能够使用 XmlWriter (C#,.NET)来创建一个XML文档,该文档多次调用生成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 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:1)

任何类型的“编写器”对象(如TextWriter,XmlWriter等)都会执行某种程度的缓冲,因为底层流完全不受其控制。换句话说,您不能依赖底层文件的长度来确定是否已对作者进行过调用。

但是具体来说,System.IO中的许多类都有一个Flush方法,比如Stream和TextWriter,它可以用来将缓冲的内容推送到磁盘,但这会产生非常脆弱的代码,在我看来。

您应该保留其他类型的状态,以确定您是否已经编写了文档的开头。

答案 2 :(得分:1)

有几件事可以阻止该方法的运作。 XmlWriter可能不会直接将代码写入流中,FileStream可能不会直接将数据写入文件,而FileInfo对象会缓存它的信息,因此您必须制作它会更新自己以获取最新的信息。

您可以使用布尔变量来跟踪它是否是第一个项目,而不是使用FileInfo对象来检查它。

或者,只需在进入调用此方法的循环之前编写文档的开头。

答案 3 :(得分:-1)

我猜其他错误,代码应该有效。您可能正在重用XmlWriter。如果在方法中本地声明XmlWriter,你仍然会收到错误吗?