В сериализации .NET Xml возможно ли сериализовать класс со свойством enum с разными тегами на основе значения свойства? - PullRequest
3 голосов
/ 25 мая 2010

У меня есть класс, содержащий свойство списка, где список содержит объекты, у которых есть свойство enum.

Когда я сериализирую это, это выглядит так:

<?xml version="1.0" encoding="ibm850"?>
<test>
  <events>
    <test-event type="changing" />
    <test-event type="changed" />
  </events>
</test>

Возможно ли, с помощью атрибутов или подобного, заставить Xml выглядеть следующим образом?

<?xml version="1.0" encoding="ibm850"?>
<test>
  <events>
    <changing />
    <changed />
  </events>
</test>

Как правило, использовать значение свойства enum для определения имени тега? Является ли использование иерархии классов (т.е. создание подклассов вместо использования значения свойства) единственным способом?

Редактировать : После тестирования кажется, что даже иерархия классов на самом деле не будет работать. Если есть способ структурировать классы, чтобы получить желаемый результат, даже с подклассами, это также приемлемый ответ.

Вот пример программы, которая выведет вышеуказанный Xml (не забудьте нажать Ctrl + F5 для запуска в Visual Studio, в противном случае окно программы закроется немедленно):

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace ConsoleApplication18
{
    public enum TestEventTypes
    {
        [XmlEnum("changing")]
        Changing,

        [XmlEnum("changed")]
        Changed
    }
    [XmlType("test-event")]
    public class TestEvent
    {
        [XmlAttribute("type")]
        public TestEventTypes Type { get; set; }
    }
    [XmlType("test")]
    public class Test
    {
        private List<TestEvent> _Events = new List<TestEvent>();

        [XmlArray("events")]
        public List<TestEvent> Events { get { return _Events; } }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Test test = new Test();
            test.Events.Add(new TestEvent { Type = TestEventTypes.Changing });
            test.Events.Add(new TestEvent { Type = TestEventTypes.Changed });

            XmlSerializer serializer = new XmlSerializer(typeof(Test));
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "");
            serializer.Serialize(Console.Out, test, ns);
        }
    }
}

Ответы [ 2 ]

1 голос
/ 29 мая 2010
    public class Test : IXmlSerializable
    {
        private List<TestEvent> _Events = new List<TestEvent>();

        public List<TestEvent> Events { get { return _Events; } }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            throw new NotImplementedException();
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteStartElement("events");
            foreach (var item in Events)
            {
                writer.WriteElementString(item.Type.ToString().ToLower(), "");
            }
            writer.WriteEndElement();
        }

        #endregion
    }

Если вы измените класс Test на этот, он выдаст желаемый результат. Единственная проблема заключается в том, что я не думаю, что вы можете использовать тег XmlType в классе Test при переопределении разделения, поэтому имя будет Test вместо test.

0 голосов
/ 28 мая 2010

Я бы предположил, что что-то подобное невозможно с метатегами XmlType. Возможно, вам повезет больше, изучая класс DataContractSerializer. Вы также можете попытаться переопределить событие OnSerializing, но я не думаю, что это сработает.

...