在新元素中将 属性 序列化为 Xml 属性
Serialize Property as Xml Attribute in new Element
我有一个简单的class
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; }
}
如果我使用默认的 XmlSerializer 序列化 People 实例,那么我将得到
<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>
看来您必须将 xml 转换为自定义格式,因此您必须在 Person
class 对象中实现 IXmlSerializable
接口。
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");
我有一个简单的class
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; }
}
如果我使用默认的 XmlSerializer 序列化 People 实例,那么我将得到
<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>
看来您必须将 xml 转换为自定义格式,因此您必须在 Person
class 对象中实现 IXmlSerializable
接口。
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");