我有一个简单的课程
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>
答案 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();
}
序列化输出:
反序列化的输出
您还可以创建一个自定义方法来读取和写入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");