我正在尝试以流方式编写一个非常大的XML文档。而不是编写可能消耗太多内存的XDocument
或XElement
,我的想法是使用XmlWriter
编写根元素,然后将多个XElements写入该编写器,在关闭根元素之前,在另一个之后。但是,我还没有找到办法。要模拟问题,请考虑以下代码:
using System;
using System.Xml;
using System.Xml.Linq;
internal static class Program
{
private static void Main()
{
var settings = new XmlWriterSettings { Encoding = Console.OutputEncoding, Indent = true };
using (var writer = XmlWriter.Create(Console.Out, settings))
{
const string namespaceUri = "http://example.com/";
writer.WriteStartElement("x", "root", namespaceUri);
XNamespace x = namespaceUri;
XElement element = new XElement(x + "test");
element.Save(writer);
writer.WriteEndElement();
}
Console.WriteLine();
}
}
程序在element.Save(writer);
行上失败,InvalidOperationException
:“状态元素开始标记中的标记StartDocument将导致无效的XML文档”。
此异常的原因很明显:XElement假设它拥有整个XmlWriter,并在其上调用WriteStartDocument()
。显然失败了,因为文档已经启动,并且已经有一个start元素。
请注意,如果我使用XDocument
,我会期望这种行为,但我不是,我正在使用XElement
。
另一种方法是写
writer.WriteRaw(element.ToString());
而不是
element.Save(writer);
它的工作原理是它不会崩溃,从某种意义上说它可以生成正确的XML。
但是,我不喜欢它,因为它不会产生我正在寻找的干净而有效的XML(它不必要地重复命名空间声明)。它显然不能,因为XElement是在没有XmlWriter应该提供的上下文的情况下序列化的。需要中间字符串才能工作的事实甚至不是最大的问题。
我应该如何以一种有效的方式将多个XElement
实例一个接一个地写入XmlWriter
,以便生成干净的XML?或者这不可能吗?
答案 0 :(得分:11)
如果您将element.Save(writer);
更改为element.WriteTo(writer);
,则没有异常,它似乎已写入控制台。