【问题标题】:Building an XML file iteratively with XmlWriter使用 XmlWriter 迭代构建 XML 文件
【发布时间】:2011-01-02 22:09:48
【问题描述】:

我希望能够使用 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 的调用实际上并未被写入,因为在随后的每次调用中,文档都会重新开始。

谁能告诉我为什么会这样?

【问题讨论】:

    标签: c# .net xml xmlwriter


    【解决方案1】:

    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();
    }
    

    【讨论】:

    • 你知道有什么方法可以在我写完之后让作者继续打开以供以后使用,同时可以选择关闭它和任何剩余的标签吗?关闭作者的问题在于它会关闭所有打开的标签,我希望它们保持打开状态,直到我自己明确关闭它们。
    • 我的第一个问题一定仍然有类似的问题。我外部化了 WriteStartDocument 调用和我的文件,在调用 WriteStartDocument 和几个到几个 WriteElement 方法后,仍然返回一个错误,指出只需要调用 WriteStartDocument 一次。我正在检查是否使用 !(File.Length == 0) 调用写入了任何内容。
    【解决方案2】:

    任何类型的“写入器”对象,如 TextWriter、XmlWriter 等,都会进行某种程度的缓冲,就像完全不受其控制的底层流一样。换句话说,您不能依靠基础文件的长度来确定是否已经对编写器进行了先前的调用。

    但具体来说,System.IO 中的许多类(例如 Stream 和 TextWriter)都有一个 Flush 方法,可用于将缓冲的内容推送到磁盘,但这会导致代码非常脆弱,在我的意见。

    您应该维护一些其他类型的状态来确定您是否已经编写了文档的开头。

    【讨论】:

      【解决方案3】:

      有几件事可以使该方法无法正常工作。 XmlWriter 可能不会直接将代码写入流,FileStream 可能不会直接将数据写入文件,FileInfo 对象会缓存它的信息,因此您必须使其自我更新以获取信息这是最新的。

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

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

      【讨论】:

        【解决方案4】:

        我猜还有其他问题,该代码应该可以工作。您可能正在重用 XmlWriter。如果在方法中本地声明 XmlWriter 是否还会报错?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多