views:

143

answers:

2

I have a class, containing a list property, where the list contains objects that has an enum property.

When I serialize this, it looks like this:

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

Is it possible, through attributes, or similar, to get the Xml to look like this?

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

Basically, use the property value of the enum as a way to determine the tag-name? Is using a class hierarchy (ie. creating subclasses instead of using the property value) the only way?

Edit: After testing, it seems even a class-hierarchy won't actually work. If there is a way to structure the classes to get the output I want, even with sub-classes, that is also an acceptable answer.

Here's a sample program that will output the above Xml (remember to hit Ctrl+F5 to run in Visual Studio, otherwise the program window will close immediately):

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);
        }
    }
}
A: 

I would assume that something like this is not possible with the the XmlType meta tags. You might have more luck looking into the DataContractSerializer class. You could also try to override the OnSerializing event but I dont think that is going to work.

Jeff
+1  A: 
    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
    }

If you change the Test class to this it produces sort of the output you want. The only problem is that I dont think you can use an XmlType tag on the Test class when overriding seralization so the name will be Test instead of test.

alun