Используя интерфейс IXmlSerializable на диаграмме составного объекта

При использовании пользовательской Сериализации XML (IXmlSerialiable), на сложном объекте, который содержит свойства с составляющими сложными объектами, которые НЕ используют пользовательский IXmlSerializable интерфейс, как Вы указываете, в IXmlSerializable.ReadXml(XmlReader reader) метод, что Вы хотите, чтобы deserializer использовал обычную десериализацию на тех дочерних свойствах?

Примечание: подобный этому вопросу

6
задан Community 23 May 2017 в 12:15
поделиться

1 ответ

IXmlSerializable немного утомительно реализовать, поскольку это в значительной степени подход «все или ничего», учитывая, что вы не можете выбирать дочерние типы для нормальной сериализации XML. Однако, если я вас правильно понял, вы можете добиться желаемого, вручную создав XmlSerializer для типов, которые не реализуют IXmlSerializable .

Например, если мы начнем с двух классов, Default , который не реализует IXmlSerializable , и Custom , который его реализует.

public class Default // Uses default XML Serialization
{
    public int Count { get; set; }
}

public class Custom : IXmlSerializable
{
    public int Count { get; set; }

    public XmlSchema GetSchema() { throw new NotImplementedException(); }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadToDescendant("Count");
        this.Count = reader.ReadElementContentAsInt();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement("Custom");
        writer.WriteElementString("Count", this.Count.ToString());
        writer.WriteEndElement();
    }
}

Затем мы создаем третий класс Parent , который имеет дочерний элемент каждого из предыдущих экземпляров и реализует IXmlSerializable таким образом, что вызывает методы ReadXml / WriteXml . для дочернего элемента, который его поддерживает, и создать сериализатор XML по умолчанию для другого дочернего элемента.

public class Parent : IXmlSerializable
{
    public Parent()
    {
        this.Default = new Default { Count = 1 };
        this.Custom = new Custom { Count = 2 };
    }

    public Default Default { get; set; }
    public Custom Custom { get; set; }

    public XmlSchema GetSchema() { throw new NotImplementedException(); }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadToFollowing("Custom");
        this.Custom = new Custom();
        this.Custom.ReadXml(reader);

        reader.ReadToFollowing("Default");
        var serializer = new XmlSerializer(typeof(Default));
        this.Default = (Default)serializer.Deserialize(reader);
    }

    public void WriteXml(XmlWriter writer)
    {
        this.Custom.WriteXml(writer);

        var ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        new XmlSerializer(typeof(Default)).Serialize(writer, this.Default, ns);
    }
}

Чтобы завершить пример, приведен пример программы, которая сериализует и десериализует экземпляр Parent :

static void Main()
{
    var sb = new StringBuilder();
    var serializer = new XmlSerializer(typeof(Parent));

    serializer.Serialize(new StringWriter(sb), new Parent());

    Console.WriteLine(sb);

    var parent = (Parent)serializer.Deserialize(new StringReader(sb.ToString()));

    Console.WriteLine("Parent.Custom.Count: {0}", parent.Custom.Count);
    Console.WriteLine("Parent.Default.Count: {0}", parent.Default.Count);
}
7
ответ дан 17 December 2019 в 00:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: