XmlSerializer сериализует подобъекты - PullRequest
3 голосов
/ 12 июня 2009

Как вы сериализуете следующее

[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 ]

4 голосов
/ 12 июня 2009

Я не вижу никакого очевидного способа заставить его выводить эти результаты без радикального изменения классов ... это может быть не то, что вы хотите, но, отражая желаемый результат (не редкость в 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 голос
/ 14 июня 2009

Я нашел способ сделать это без использования 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());
}
0 голосов
/ 12 июня 2009

Это похоже на похожую проблему, с которой я столкнулся .. Я наконец взломал ее и разместил все по вопросу здесь ..

Сериализация XML и унаследованные типы

Это какой-то смысл?

...