在新元素中将属性序列化为Xml属性

时间:2018-12-13 12:46:05

标签: c# .net xml-serialization

我有一个简单的课程

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }

    public ICollection<Address> AllAddress { get; set; }
}

public class Address
{
    public string  Street { get; set; }
}

如果我序列化People实例使用默认的XmlSerializer,那么我会得到

<Person xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Id>2</Id>
    <Name>FIO FIO IFO</Name>
    <Address>
        <Street>Golden Gate</Street>
    </Address>
</Person>

如何获得此结果?

<struct n="People">
     <attr n="id">2</attr >
     <attr n="name">FIO FIO IFO</attr >
     <struct n="Address">
         <attr n="street">Golden Gate</attr>
     </struct >
</struct>

1 个答案:

答案 0 :(得分:2)

似乎您必须将xml转换为自定义格式,因此必须在IXmlSerializable类对象中实现Person接口。

public class Person : IXmlSerializable
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }

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

    public void ReadXml(XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.Name == "attr" && reader.GetAttribute("n") == "id")
                Id = Convert.ToInt32(reader.ReadInnerXml());

            if (reader.Name == "attr" && reader.GetAttribute("n") == "name")
                Name = reader.ReadInnerXml();

            if (reader.Name == "attr" && reader.GetAttribute("n") == "street")
                Address = new Address { Street = reader.ReadInnerXml() };
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        //Start "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "People");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "id");
        writer.WriteString(Id.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "name");
        writer.WriteString(Name.ToString());
        writer.WriteEndElement();

        //Start inner "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "Address");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "street");
        writer.WriteString(Address.Street.ToString());
        writer.WriteEndElement();

        //End inner "struct"
        writer.WriteEndElement();

        //End "struct"
        writer.WriteEndElement();
    }
}

您可以像这样对XML进行序列化和反序列化。

Person person = new Person
{
    Id = 2,
    Name = "FIO FIO IFO",
    Address = new Address { Street = "Golden Gate" }
};

//--------------------Serialization----------------------------

XmlSerializer serializer = new XmlSerializer(person.GetType());
using (StreamWriter writer = new StreamWriter(@"Path to xml file"))
{
    serializer.Serialize(writer, person);
}

//--------------------Deserialization----------------------------

using (StringReader stringReader = new StringReader(File.ReadAllText(@"Path to same xml file that generated by above serializer")))
{
    person = (Person)serializer.Deserialize(stringReader);

    Console.WriteLine("Id: " + person.Id);
    Console.WriteLine("Name: " + person.Name);
    Console.WriteLine("Street: " + person.Address.Street);

    Console.ReadLine();
}

序列化输出:

enter image description here

反序列化的输出

enter image description here


替代

您还可以创建一个自定义方法来读取和写入xml。

1)写

public static void WriteXml(Person person, string path)
{
    using (XmlWriter writer = XmlWriter.Create(path))
    {
        //Start "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "People");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "id");
        writer.WriteString(person.Id.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "name");
        writer.WriteString(person.Name.ToString());
        writer.WriteEndElement();

        //Start inner "struct"
        writer.WriteStartElement("struct");
        writer.WriteAttributeString("n", "Address");

        writer.WriteStartElement("attr");
        writer.WriteAttributeString("n", "street");
        writer.WriteString(person.Address.Street.ToString());
        writer.WriteEndElement();

        //End inner "struct"
        writer.WriteEndElement();

        //End "struct"
        writer.WriteEndElement();
    }
}

用法:

Person person = new Person
{
    Id = 2,
    Name = "FIO FIO IFO",
    Address = new Address { Street = "Golden Gate" }
};

WriteXml(person, @"Path to xml file");

2)阅读

public static Person ReadXml(string path)
{
    Person person = new Person();

    using (XmlReader reader = XmlReader.Create(path))
    {
        while (reader.Read())
        {
            if (reader.Name == "attr" && reader.GetAttribute("n") == "id")
                person.Id = Convert.ToInt32(reader.ReadInnerXml());

            if (reader.Name == "attr" && reader.GetAttribute("n") == "name")
                person.Name = reader.ReadInnerXml();

            if (reader.Name == "attr" && reader.GetAttribute("n") == "street")
                person.Address = new Address { Street = reader.ReadInnerXml() };
        }
    }

    return person;
}

用法:

Person result = ReadXml(@"Path to same xml file that generated by above serializer");