自定义Xml Serializer,将值作为xml元素

时间:2016-12-22 16:45:34

标签: c# xml-serialization

类:

public class Employee
{
    public int Id { get; set; }

    public PhoneNumber[] Numbers { get; set; }
}

public class PhoneNumber
{
    public string Type { get; set; }

    public string Number { get; set; }
}

要序列化的代码:

var xmlSerializer = new XmlSerializer(typeof(Employee));

var xwSettings = new XmlWriterSettings {Indent = true, OmitXmlDeclaration = true};

string serializedResult;
using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, xwSettings))
{
    xmlSerializer.Serialize(writer, emp);
    serializedResult = stream.ToString();
}

当前结果:

<Employee>
  <Id>1</Id>
  <Numbers>
    <PhoneNumber>
      <Type>Home</Type>
      <Number>1231231231</Number>
    </PhoneNumber>
    <PhoneNumber>
      <Type>Office</Type>
      <Number>3453453453</Number>
    </PhoneNumber>
  </Numbers>
</Employee>

期望的结果:

<Employee>
  <Id>1</Id>
  <Numbers>
    <Home>1231231231</Home>
    <Office>3453453453</Office>
  </Numbers>
</Employee>

PhoneNumber Type可以动态添加,例如&#34; GuestRoomPhone&#34;等,因此无法为每种电话号码类型添加属性。

1 个答案:

答案 0 :(得分:1)

您可以通过在类上实现IXmlSerializable接口来完成此操作。这允许您控制值的写入和读取方式。

public class Employee : IXmlSerializable
{
    public int Id { get; set; }

    public PhoneNumber[] Numbers { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement("Employee");
        reader.ReadStartElement("Id");
        Id = reader.ReadContentAsInt();
        reader.ReadEndElement();    // Id

        reader.ReadStartElement("Numbers");

        List<PhoneNumber> numbers = new List<PhoneNumber>();
        while (reader.MoveToContent() == XmlNodeType.Element)
        {
            PhoneNumber num = new PhoneNumber();
            num.ReadXml(reader);
            numbers.Add(num);
        }
        Numbers = numbers.ToArray();

        reader.ReadEndElement();    // Numbers
        reader.ReadEndElement();    // Employee
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement("Id");
        writer.WriteValue(Id);
        writer.WriteEndElement();

        writer.WriteStartElement("Numbers");

        foreach (PhoneNumber num in Numbers)
        {
            num.WriteXml(writer);
        }

        writer.WriteEndElement();   // Numbers
    }
}

同样适用于PhoneNumber类。

public class PhoneNumber : IXmlSerializable
{
    public string Type { get; set; }
    public string Number { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        while (!reader.IsStartElement())
            reader.Read();
        Type = reader.Name;
        Number = reader.ReadElementContentAsString();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteStartElement(Type);
        writer.WriteString(Number);
        writer.WriteEndElement();
    }
}