在父元素中将对象序列化为XML WITHIN

我有一个WPF C#程序,有一次我需要将对象序列化为XML。 在其他地方,我一直在使用这个:

TextWriter writer = new StreamWriter(xmlFilePath); XmlSerializer xmlSerializer = new XmlSerializer(typeof(MYOBJECT_TYPE)); try { xmlSerializer.Serialize(writer, MYOBJECT); } catch (Exception ex) { MessageBox.Show("Exception occured while writing to Xml" + ex.Message); } finally { writer.Close(); } 

这太棒了,但这意味着我必须为每个要序列化的对象提供不同的XML文件。 如何使用此方法(使用最少的修改)将对象序列化为父元素中的XML WITHIN ? 这样,当我想稍后反序列化对象时,我可以找到我想要的元素,并反序列化该元素中的所有内容。

根据要求,这里是CreateDefaultXml();

 static void CreateDefaultXml() { XmlDocument doc = new XmlDocument(); doc.LoadXml(""); XmlNode root = doc.DocumentElement; try { doc.Save(xmlFilePath); } catch (Exception ex) { Console.WriteLine("Exception occured while creating Xml" + ex.InnerException); } } 

编辑:

目前,这是我所拥有的(但它抛出exceptionThere was an error generating the XML document.

 if (!File.Exists(xmlFilePath)) CreateDefaultXml(); XDocument doc = XDocument.Load(xmlFilePath); var element = doc.Descendants("Object").Where(x => x.Attribute("Name").Value.Equals("objectName")).SingleOrDefault(); if (element == null) { element = new XElement("Object", new XAttribute("Name", objectName)); doc.Element("StoredObjects").Add(element); } XmlWriter writer = element.CreateWriter(); XmlSerializer xmlSerializer = new XmlSerializer(typeof(MYOBJECT_TYPE)); try { xmlSerializer.Serialize(writer, MYOBJECT); } catch (Exception ex) { MessageBox.Show("Exception occured while writing to Xml: " + ex.Message); } finally { writer.Close(); doc.Save(xmlFilePath); } 

您正在尝试使用XmlSerializer直接序列化到XDocument某个嵌套XElement 。 不幸的是,似乎在使用XmlSerializerXContainer.CreateWriter()直接序列化到LINQ-to-XML XElement ,实际上有必要序列化为空的XDocument从而创建其根元素。 (我不确定为什么存在这种限制,但确实如此。)由于这不符合您的需求,因此很容易序列化到临时 XDocument ,删除其根节点,然后将该节点添加到整个元素层次结构中。

此外,使用已存储XML数据的objectName将对象添加到数据库时,需要删除旧数据。

我将您的代码重构为扩展方法来完成此任务:

 public static class XmlExtensions { public static T Deserialize(this XContainer element, XmlSerializer serializer = null) { using (var reader = element.CreateReader()) { object result = (serializer ?? new XmlSerializer(typeof(T))).Deserialize(reader); if (result is T) return (T)result; } return default(T); } public static XElement SerializeToXElement(this T obj, XmlSerializer serializer = null) { var doc = new XDocument(); using (var writer = doc.CreateWriter()) (serializer ?? new XmlSerializer(obj.GetType())).Serialize(writer, obj); var element = doc.Root; if (element != null) element.Remove(); return element; } public static XName ContainerElementName { get { return (XName)"Object"; } } public static XName ContainerAttributeName { get { return (XName)"Name"; } } public static XElement SetItem(this XDocument doc, string attributeValue, T obj) { return doc.SetItem(ContainerElementName, ContainerAttributeName, attributeValue, obj); } static XElement SetItem(this XDocument doc, XName containerElementName, XName containerAttributeName, string attributeValue, T obj) { if (doc == null || containerElementName == null || containerAttributeName == null || attributeValue == null) throw new ArgumentNullException(); if (doc.Root == null) throw new ArgumentException("doc.Root == null"); var container = doc.Root.Elements(containerElementName).Where(e => (string)e.Attribute(containerAttributeName) == attributeValue).SingleOrDefault(); if (container == null) { container = new XElement(containerElementName, new XAttribute(containerAttributeName, attributeValue)); doc.Root.Add(container); } else { // Remove old content. container.RemoveNodes(); } var element = obj.SerializeToXElement(); container.Add(element); return element; } public static T GetItem(this XDocument doc, string attributeValue) { return doc.GetItem(ContainerElementName, ContainerAttributeName, attributeValue); } static T GetItem(this XDocument doc, XName containerElementName, XName containerAttributeName, string attributeValue) { if (doc == null || containerElementName == null || containerAttributeName == null || attributeValue == null) throw new ArgumentNullException(); if (doc.Root == null) throw new ArgumentException("doc.Root == null"); var container = doc.Root.Elements(containerElementName).Where(e => (string)e.Attribute(containerAttributeName) == attributeValue).SingleOrDefault(); if (container == null) return default(T); var element = container.Elements().SingleOrDefault(); if (element == null) return default(T); return element.Deserialize(); } public static XDocument CreateDefaultXDocument() { var xml = @""; return XDocument.Parse(xml); } } 

现在你可以做到

 doc.AddItem(MYOBJECT, objectName); 

然后

 var MYOBJECT2 = doc.GetItem(objectName); 

示例小提琴 。