您正在尝试直接序列化到某些嵌套的XElement
里面一个XDocument
using XmlSerializer
。不幸的是,当直接序列化到 LINQ-to-XML 时XElement
using XmlSerializer
和...一起XContainer.CreateWriter(),实际上需要序列化为空XDocument
从而创建其根元素。 (我不确定为什么存在这个限制,但确实存在。)由于这不能满足您的需求,因此很容易序列化为暂时的 XDocument
,删除其根节点,然后将该节点添加到整个元素层次结构中。
此外,当使用objectName
如果已经存储了 XML 数据,则需要删除旧数据。
我将您的代码重构为扩展方法来实现此目的:
public static class XmlExtensions
{
public static T Deserialize<T>(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<T>(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<T>(this XDocument doc, string attributeValue, T obj)
{
return doc.SetItem(ContainerElementName, ContainerAttributeName, attributeValue, obj);
}
static XElement SetItem<T>(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<T>(this XDocument doc, string attributeValue)
{
return doc.GetItem<T>(ContainerElementName, ContainerAttributeName, attributeValue);
}
static T GetItem<T>(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<T>();
}
public static XDocument CreateDefaultXDocument()
{
var xml = @"<StoredObjects></StoredObjects>";
return XDocument.Parse(xml);
}
}
现在你可以做
doc.AddItem(MYOBJECT, objectName);
然后
var MYOBJECT2 = doc.GetItem<MYOBJECT_TYPE>(objectName);
Example fiddle.