1

我希望能够使用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

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 等,都会进行某种程度的缓冲,就像完全不受其控制的底层流一样。换句话说,您不能依赖基础文件的长度来确定是否已经对编写器进行了先前的调用。

但具体来说,System.IO 中的许多类(例如 Stream 和 TextWriter)都有一个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 回答