在.NET Xml序列化中,是否可以根据属性值序列化具有不同标记的枚举属性的类?

时间:2010-05-24 21:51:18

标签: c# .net xml-serialization tagname

我有一个包含list属性的类,其中列表包含具有枚举属性的对象。

当我序列化它时,它看起来像这样:

<?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>

基本上,使用枚举的属性值作为确定标记名称的方法?使用类层次结构(即创建子类而不是使用属性值)是唯一的方法吗?

编辑:测试后,甚至类层次结构似乎也无法正常工作。如果有一种方法来构造类来获得我想要的输出,即使是子类,这也是一个可接受的答案。

这是一个示例程序,它将输出上面的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 个答案:

答案 0 :(得分:1)

    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类更改为此类,则会生成所需的输出。唯一的问题是我不认为你可以在重写seralization时在Test类上使用XmlType标签,因此名称将是Test而不是test。

答案 1 :(得分:0)

我认为使用XmlType元标记无法实现这样的功能。您可能有更多的运气查看DataContractSerializer类。您也可以尝试覆盖OnSerializing事件,但我认为这不会起作用。