Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在父元素中将对象序列化为XML_C#_Xml_Wpf_Serialization - Fatal编程技术网

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

C# 在父元素中将对象序列化为XML,c#,xml,wpf,serialization,C#,Xml,Wpf,Serialization,我有一个WPF C#程序,有一次我需要将对象序列化为XML。在其他地方,我一直在使用: TextWriter writer = new StreamWriter(xmlFilePath); XmlSerializer xmlSerializer = new XmlSerializer(typeof(MYOBJECT_TYPE)); try { xmlSerializer.Serialize(writer, MYOBJECT); } catch (Exception ex) {

我有一个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?这样,当我以后想要反序列化对象时,我可以找到我想要的元素,并反序列化该元素中的所有内容

根据要求,这里是
CreateDefaultXml()


您正试图使用
XmlSerializer
直接序列化到
XDocument
中的某个嵌套
XElement
。不幸的是,当与一起使用
XmlSerializer
直接序列化到LINQ to XML
XElement
时,实际上需要序列化到空的
XDocument
,从而创建其根元素。(我不确定为什么会存在此限制,但它确实存在。)由于这不满足您的需要,因此可以轻松地序列化到临时
XDocument
,删除其根节点,然后将该节点添加到整个元素层次结构中

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

为了实现这一点,我将您的代码重构为扩展方法:

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);
    }
}
后来

var MYOBJECT2 = doc.GetItem<MYOBJECT_TYPE>(objectName);
var MYOBJECT2=doc.GetItem(objectName);

示例。

您试图使用
XmlSerializer
直接序列化到
XDocument
中的某个嵌套的
XElement
。不幸的是,当与一起使用
XmlSerializer
直接序列化到LINQ to XML
XElement
时,实际上需要序列化到空的
XDocument
,从而创建其根元素。(我不确定为什么会存在此限制,但它确实存在。)由于这不满足您的需要,因此可以轻松地序列化到临时
XDocument
,删除其根节点,然后将该节点添加到整个元素层次结构中

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

为了实现这一点,我将您的代码重构为扩展方法:

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);
    }
}
后来

var MYOBJECT2 = doc.GetItem<MYOBJECT_TYPE>(objectName);
var MYOBJECT2=doc.GetItem(objectName);

示例。

1)什么是
形状
?在
shape.CreateWriter()行中它未定义。2) 您能否共享
CreateDefaultXml()?@dbc对不起。我已经更新了问题。我更改了
消息框。Show
以显示
ex.InnerException
并获取
System.InvalidOperationException:WriteStartDocument不能在使用ConformanceLevel.Fragment创建的写入程序上调用。
1)什么是
形状
?在
shape.CreateWriter()行中它未定义。2) 您能否共享
CreateDefaultXml()?@dbc对不起。我已经更新了问题。我更改了
消息框。Show
以显示
ex.InnerException
并获取
System.InvalidOperationException:WriteStartDocument不能在使用ConformanceLevel.Fragment创建的写入程序上调用。
var MYOBJECT2 = doc.GetItem<MYOBJECT_TYPE>(objectName);