.net中的流式XML序列化
我正在尝试使用XmlSerializer
序列化一个非常大的IEnumerable
,而不会将所有对象保留在内存中。
IEnumerable
实际上是懒惰的..
我正在寻找一种流媒体解决方案:
- 使用标准序列化从
IEnumerable
序列化到底层流中的对象( 我不想在这里手工处理XML! ) - 丢弃内存数据并移至下一个
我正在尝试使用此代码:
using (var writer = new StreamWriter(filePath)) { var xmlSerializer = new XmlSerializer(typeof(MyObject)); foreach (var myObject in myObjectsIEnumerable) { xmlSerializer.Serialize(writer, myObject); } }
但我得到多个XML标头,我无法指定根标签所以我的XML无效。
任何的想法?
谢谢
XmlWriter
类是用于生成XML的快速流API。 它是相当低级的,MSDN有一篇关于使用XmlWriter.Create()
实例化validationXmlWriter的文章 。
编辑:链接已修复。 以下是文章中的示例代码:
async Task TestWriter(Stream stream) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Async = true; using (XmlWriter writer = XmlWriter.Create(stream, settings)) { await writer.WriteStartElementAsync("pf", "root", "https://ns"); await writer.WriteStartElementAsync(null, "sub", null); await writer.WriteAttributeStringAsync(null, "att", null, "val"); await writer.WriteStringAsync("text"); await writer.WriteEndElementAsync(); await writer.WriteCommentAsync("cValue"); await writer.WriteCDataAsync("cdata value"); await writer.WriteEndElementAsync(); await writer.FlushAsync(); } }
这是我使用的:
using System; using System.Collections.Generic; using System.Xml; using System.Xml.Serialization; using System.Text; using System.IO; namespace Utils { public class XMLSerializer { public static Byte[] StringToUTF8ByteArray(String xmlString) { return new UTF8Encoding().GetBytes(xmlString); } public static String SerializeToXML(T objectToSerialize) { StringBuilder sb = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings {Encoding = Encoding.UTF8, Indent = true}; using (XmlWriter xmlWriter = XmlWriter.Create(sb, settings)) { if (xmlWriter != null) { new XmlSerializer(typeof(T)).Serialize(xmlWriter, objectToSerialize); } } return sb.ToString(); } public static void DeserializeFromXML (string xmlString, out T deserializedObject) where T : class { XmlSerializer xs = new XmlSerializer(typeof (T)); using (MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(xmlString))) { deserializedObject = xs.Deserialize(memoryStream) as T; } } } }
然后打电话:
string xml = Utils.SerializeToXML(myObjectsIEnumerable);
我没有试过它,例如, IEnumerable
一次一个地获取一个对象,或任何其他奇怪的用例,但它适用于List
和内存中的其他集合。
编辑 :根据您对此的评论,您可以使用XmlDocument.LoadXml
将生成的XML字符串加载到XmlDocument
,将第一个XML字符串保存到文件中,并将其用作主XML文件。 对于IEnumerable
中的每个项目,再次使用LoadXml
创建一个新的内存中XmlDocument
,获取所需的节点,将它们附加到主文档,然后再次保存,删除新的。
完成后,可能有一种方法可以包装根标记中的所有节点。 您还可以使用XSL和XslCompiledTransform
编写另一个XML文件,其中包含正确包装在根标记中的对象。
您可以通过在大类上实现IXmlSerializable
接口来完成此操作。 WriteXml
方法的实现可以编写开始标记,然后简单地遍历IEnumerable
并将每个MyObject
序列化为同一个XmlWriter
,一次一个。
在此实现中,将不会有任何内存中的数据(废弃收集器将收集的内容)。
上述就是C#学习教程:.net中的流式XML序列化分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1022788.html