【问题标题】:Partially deserialize XML to Object将 XML 部分反序列化为 Object
【发布时间】:2011-01-04 22:35:11
【问题描述】:

我有一些可反序列化为业务对象的 XML。我正在使用 XmlSerializer.Deserialize 这样做。但是,我希望 XML 中包含的其中一个 XmlElement 保持为 XElement。

它不能直接完成(使用 XmlElementAttribute),因为 XElement 不是可序列化的。我还尝试将该元素序列化为字符串(分两步尝试获取 XElement),但失败并出现错误:

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

知道怎么做吗?

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

<Person name="Joe">
  <Hobbies>
    <Hobby name="Reading" .../>
    <Hobby name="Photography" .../>
  </Hobbies>
  <HomeAddress>
    ...
  </HomeAddress>
</Person>

对象:

 public class Person
    {
      [XmlAttribute("Name")]
      public string Name {get; set;}
      ?????
      public XElement Hobbies {get; set;}
      [XmlElement("HomeAddress")]
      public Address HomeAddress {get; set;}
    }

无效的尝试:

[XmlElement("Hobbies")]
public XElement Hobbies {get; set;}
[XmlElement("Hobbies")]
public string Hobbies {get; set;}

【问题讨论】:

    标签: c# xml serialization xelement


    【解决方案1】:

    为了避免实现类似IXmlSerializable 的繁重工作,您可能会按照半隐藏的直通XmlElement 属性的方式做一些事情;但是请注意,这并不完全符合您的要求,因为您只能有一个根 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,所以我只是在“爱好”节点周围添加了一个包装器节点来获得我需要的东西(而不是使用列表)。非常感谢。
    【解决方案2】:

    要完全控制(以及全部责任)如何生成 XML,您可以让您的类实现 System.Xml.Serialization.IXmlSerializable 接口,并覆盖 ReadXml 和 WriteXml。我以前必须用字典类来做这件事——一定要彻底测试,尤其是空属性、空字段等。

    http://www.devx.com/dotnet/Article/29720

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      • 2017-08-15
      相关资源
      最近更新 更多