Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.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_Serialization_Xelement - Fatal编程技术网

C# 将XML部分反序列化为对象

C# 将XML部分反序列化为对象,c#,xml,serialization,xelement,C#,Xml,Serialization,Xelement,我有一些反序列化为业务对象的XML。我正在使用XmlSerializer.Deserialize来执行此操作。但是,我希望XML中包含的一个XmlElement保持为XElement 由于XElement不可序列化,因此无法直接执行(使用XmlElementAttribute)。我还尝试将该元素序列化为字符串(通过两步尝试获取XElement),但失败了,出现错误: 意外的节点类型元素。 readelementstring方法只能是 使用简单或 空内容 你知道怎么做吗 下面是一个xml示例和我想

我有一些反序列化为业务对象的XML。我正在使用XmlSerializer.Deserialize来执行此操作。但是,我希望XML中包含的一个XmlElement保持为XElement

由于XElement不可序列化,因此无法直接执行(使用XmlElementAttribute)。我还尝试将该元素序列化为字符串(通过两步尝试获取XElement),但失败了,出现错误:

意外的节点类型元素。 readelementstring方法只能是 使用简单或 空内容

你知道怎么做吗

下面是一个xml示例和我想要的结果对象:

<Person name="Joe">
  <Hobbies>
    <Hobby name="Reading" .../>
    <Hobby name="Photography" .../>
  </Hobbies>
  <HomeAddress>
    ...
  </HomeAddress>
</Person>
不起作用的尝试:

[XmlElement("Hobbies")]
public XElement Hobbies {get; set;}
[XmlElement("Hobbies")]
public string Hobbies {get; set;}
要完全控制(以及完全负责)XML的生成方式,可以让类实现System.XML.Serialization.IXmlSerializable接口,并重写ReadXml和WriteXml。我以前在使用字典类时必须这样做——确保彻底测试,尤其是使用空属性、空字段等


为了避免实现像
IXmlSerializable
这样的东西的困难工作,您可以按照半隐藏的传递
XmlElement
属性来做一些事情;但是,请注意,这并不能完全满足您的需要,因为您只能有一个root
XElement
值(根据您的示例,不是两个);你需要一份清单来做这件事

using System;
using System.ComponentModel;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
public class Person
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlIgnore]
    public XElement Hobbies { get; set; }

    [XmlElement("Hobbies")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public XmlElement HobbiesSerialized
    {
        get
        {
            XElement hobbies = Hobbies;
            if(hobbies == null) return null;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(hobbies.ToString());
            return doc.DocumentElement;
        }
        set
        {
            Hobbies = value == null ? null
                : XElement.Parse(value.OuterXml);
        }
    }
    [XmlElement("HomeAddress")]
    public Address HomeAddress { get; set; }
}

public class Address { }

static class Progmam
{
    static void Main()
    {
        var p = new Person { Hobbies = new XElement("xml", new XAttribute("hi","there")) };
        var ser = new XmlSerializer(p.GetType());
        ser.Serialize(Console.Out, p);
    }
}

很不错的。我不明白为什么在将XmlElementAttribute指定为“嗜好”时需要内部节点。但是,我可以控制XML,所以我只是在“嗜好”节点周围添加了一个包装器节点,以获得我需要的内容(而不是使用列表)。谢谢。
using System;
using System.ComponentModel;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
public class Person
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlIgnore]
    public XElement Hobbies { get; set; }

    [XmlElement("Hobbies")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public XmlElement HobbiesSerialized
    {
        get
        {
            XElement hobbies = Hobbies;
            if(hobbies == null) return null;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(hobbies.ToString());
            return doc.DocumentElement;
        }
        set
        {
            Hobbies = value == null ? null
                : XElement.Parse(value.OuterXml);
        }
    }
    [XmlElement("HomeAddress")]
    public Address HomeAddress { get; set; }
}

public class Address { }

static class Progmam
{
    static void Main()
    {
        var p = new Person { Hobbies = new XElement("xml", new XAttribute("hi","there")) };
        var ser = new XmlSerializer(p.GetType());
        ser.Serialize(Console.Out, p);
    }
}