4

是否可以重用 XmlTextWriter 类的相同实例来生成更多 xml 文档?我的意思是这样的:

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 可扩展标记语言 (XML) 1.0 和 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() 之后,那么即使您 Flush() Writer 并将 Stream 长度设置为 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

我猜flush会做你所要求的。只需构建和检索 XML、刷新、冲洗、重复;)

干杯。

于 2011-02-07T08:23:31.863 回答