Сериализация полиморфного списка НО не может изменить определения типов - PullRequest
0 голосов
/ 10 июня 2018

Я использую DLL другой стороны, которая определяет классы животных, кошек, рыб.

//Begin another party's DLL
public class animals
{
}

public class cat : animals
{
    public string size { get; set; }
    public string furColor { get; set; }
}

public class fish : animals
{
    public string size { get; set; }
    public string scaleColor { get; set; }
}
//End another party's DLL

static void Main(string[] args)
{

    using (var xmlWriter = XmlWriter.Create("a.xml", new XmlWriterSettings { Indent = true }))
    {
        var eventArgsList = new List<animals>();
        eventArgsList.Add(new cat { size = "10", furColor = "red" });
        eventArgsList.Add(new fish { size = "20", scaleColor = "blue" });

        new XmlSerializer(eventArgsList.GetType(),new[] { typeof(cat), typeof(fish) }).Serialize(xmlWriter, eventArgsList);
    }
}

Приведенный выше код корректно выводит

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfAnimals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <animals xsi:type="cat">
    <size>10</size>
    <furColor>red</furColor>
  </animals>
  <animals xsi:type="fish">
    <size>20</size>
    <scaleColor>blue</scaleColor>
  </animals>
</ArrayOfAnimals>

Однако я хочу, чтобы он выглядел как

<?xml version="1.0" encoding="utf-8"?>
<Animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <cat>
    <size>10</size>
    <furColor>red</furColor>
  </cat>
  <fish>
    <size>20</size>
    <scaleColor>blue</scaleColor>
  </fish>
</Animals>

Конечно, это похоже на Сериализация полиморфногоСписок с тем же именем типа , но я не могу изменить определение типа.Я думаю, что я должен использовать XmlAttributeOverrides, кто-нибудь может сказать мне, как это сделать?

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Вдохновленный инновационным подходом CodingYoshi, я считаю, что следующий класс помощников работает короче на 100 строк.

[XmlRoot("Animals")]
public class AnimalsHelper
{
    [XmlElement("Cat", typeof(cat))]
    [XmlElement("Fish", typeof(fish))]
    public List<animals> Animals { get; set; } = new List<animals>();
}

static void Main(string[] args)
{

    using (var xmlWriter = XmlWriter.Create("a.xml", new XmlWriterSettings { Indent = true }))
    {
        var animalsHelper= new AnimalsHelper();
        animalsHelper.Animals.Add(new cat { size = "10", furColor = "red" });
        animalsHelper.Animals.Add(new fish { size = "20", scaleColor = "blue" });

        new XmlSerializer(animalsHelper.GetType(),new[] { typeof(cat), typeof(fish) }).Serialize(xmlWriter, animalsHelper);
    }

    using (var xmlReader = XmlReader.Create("a.xml", new XmlReaderSettings { IgnoreWhitespace = true }))
    {
        var obj = (AnimalsHelper)new XmlSerializer(animalsHelper.GetType(), new[] { typeof(cat), typeof(fish) }).Deserialize(xmlReader);

    }
}

Я все еще жажду решения без использования вспомогательных классов.

0 голосов
/ 10 июня 2018

Чтобы иметь эту структуру в XML без написания настраиваемого сериализатора, вам необходимо иметь такую ​​же структуру в ваших классах C #.Но это легко, потому что Visual Studio сделает это за вас.

Скопируйте желаемый XML и создайте классы для этой структуры XML .Это создаст следующие классы.Вам нужно сделать одну настройку и установить AnonymousType = false, как я сделал ниже.

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Animals
{

    private AnimalsCat[] catField;

    private AnimalsFish[] fishField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("cat")]
    public AnimalsCat[] cat
    {
        get
        {
            return this.catField;
        }
        set
        {
            this.catField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("fish")]
    public AnimalsFish[] fish
    {
        get
        {
            return this.fishField;
        }
        set
        {
            this.fishField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
public partial class AnimalsCat
{

    private byte sizeField;

    private string furColorField;

    /// <remarks/>
    public byte size
    {
        get
        {
            return this.sizeField;
        }
        set
        {
            this.sizeField = value;
        }
    }

    /// <remarks/>
    public string furColor
    {
        get
        {
            return this.furColorField;
        }
        set
        {
            this.furColorField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)]
public partial class AnimalsFish
{

    private byte sizeField;

    private string scaleColorField;

    /// <remarks/>
    public byte size
    {
        get
        {
            return this.sizeField;
        }
        set
        {
            this.sizeField = value;
        }
    }

    /// <remarks/>
    public string scaleColor
    {
        get
        {
            return this.scaleColorField;
        }
        set
        {
            this.scaleColorField = value;
        }
    }
}

Использование

using (var xmlWriter = XmlWriter.Create("a.xml", new XmlWriterSettings { Indent = true }))
{
    var eventArgsList = new Animals();
    eventArgsList.cat = new AnimalsCat[1]; // set this based on the number 
    eventArgsList.fish = new AnimalsFish[2]; // set this based on the number 

    // Do this using a loop but I just hard coded it
    eventArgsList.cat[0] = new AnimalsCat { size = 10, furColor = "red" };
    eventArgsList.fish[0] = new AnimalsFish { size = 20, scaleColor = "blue" };
    eventArgsList.fish[1] = new AnimalsFish { size = 30, scaleColor = "orange" };

    new XmlSerializer(eventArgsList.GetType(), new[] { typeof(AnimalsCat), typeof(AnimalsFish) }).Serialize(xmlWriter, eventArgsList);
}

Выход

<?xml version="1.0" encoding="utf-8"?>
<Animals xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <cat>
    <size>10</size>
    <furColor>red</furColor>
  </cat>
  <fish>
    <size>20</size>
    <scaleColor>blue</scaleColor>
  </fish>
  <fish>
    <size>30</size>
    <scaleColor>orange</scaleColor>
  </fish>
</Animals>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...