XmlSerializer序列化子对象

时间:2009-06-12 07:26:52

标签: c# .net xml-serialization

如何序列化以下

[XmlRoot("response")]
public class MyCollection<T>
{
    [XmlElement("person", Type = typeof(Person))]
    public List<T> entry;
    public int startIndex;
}

其中T可以是类似

的类
public class Person
{
    public string name;
}

<response>
  <startIndex>1</startIndex>
  <entry>
      <person>
         <name>meeee</name>
      </person>
  </entry>
  <entry>
      <person>
         <name>youuu</name>
      </person>
  </entry>
</response>

我一直在玩[XmlArray],[XmlArrayItem]和[XmlElement],我似乎无法获得正确的组合。 Arrrgghhh。

更新

[XmlArray("entry")]
[XmlArrayItem("person", Type = typeof(Person))]
public List<T> entry;

给了我

<entry><person></person><person></person></entry>


[XmlElement("person", Type = typeof(Person))]
public List<T> entry;

给了我

<person></person><person></person>

3 个答案:

答案 0 :(得分:4)

我看不出任何明显的方法让它输出那些结果而不从根本上改变类...这可能不是你想要的,但通过镜像所需的输出(在DTO中并不罕见)它得到了正确的结果...

否则,你可能会看IXmlSerializable,这是一个巨大的痛苦:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;
[XmlRoot("response")]
public class MyResponse {
    public MyResponse() {
        Entries = new List<Entry>();
    }
    [XmlElement("startIndex", Order = 1)]
    public int StartIndex { get; set; }
    [XmlElement("entry", Order = 2)]
    public List<Entry> Entries { get; set; }
}
public class Entry {
    public Entry() { }
    public Entry(Person person) { Person = person; }
    [XmlElement("person")]
    public Person Person { get; set; }
    public static implicit operator Entry(Person person) {
        return person == null ? null : new Entry(person);
    }
    public static implicit operator Person(Entry entry) {
        return entry == null ? null : entry.Person;
    }
}
public class Person {
    [XmlElement("name")]
    public string Name { get; set; }
}
static class Program {
    static void Main() {
        MyResponse resp = new MyResponse();
        resp.StartIndex = 1;
        resp.Entries.Add(new Person { Name = "meeee" });
        resp.Entries.Add(new Person { Name = "youuu" });
        XmlSerializer ser = new XmlSerializer(resp.GetType());
        ser.Serialize(Console.Out, resp);
    }
}

答案 1 :(得分:1)

我找到了一种不使用IXmlSerializable的方法。使用XmlDictionaryWriter格式化必要的部分,其余部分只需坚持使用DataContractSerializer。我为MyCollection创建了一个界面

public interface IMyCollection
{
    int getStartIndex();
    IList getEntry();
}

因此,MyCollection不再使用任何XMLxxxx属性进行修饰。转换为字符串的方法如下。可以改进吗?

public string ConvertToXML(object obj)
{
    MemoryStream ms = new MemoryStream();
    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(ms, Encoding.UTF8, true))
    {
         writer.WriteStartDocument();
         if (obj is IMyCollection)
         {
              IMyCollection collection = (IMyCollection)obj;
              writer.WriteStartElement("response");
              writer.WriteElementString("startIndex","0");
              var responses = collection.getEntry();
              foreach (var item in responses)
              {
                   writer.WriteStartElement("entry");
                   DataContractSerializer ser = new DataContractSerializer(item.GetType());                
                   ser.WriteObject(writer, item);
                   writer.WriteEndElement();
              }
              writer.WriteEndElement();
        }
        writer.Flush();
        return Encoding.UTF8.GetString(ms.ToArray());
}

答案 2 :(得分:0)

这听起来像是我遇到的类似问题..我终于破解了它,并在问题here上张贴了所有内容。

XML Serialization and Inherited Types

有用吗?