xml序列化及反序列化.net对象

xml在项目中的应用非常广泛,比如可以用来作为不同模块之间接口交互的数据格式,或用来对数据进行本地化的存储(如配置文件)。命名空间System.Xml.Serialization提供了对xml进行反序列化及对对象序列化的功能,使用进来非常方便。

这里举一个简单的例子进行说明。假如在需求中有一个关于"学校"的定义,这间学校的数据结构可能是这样子的:

此外,我们还需要定义学生、老师及校长的数据结构。

有了数据模型后,相应的xml也可以写出来了。一间学校的xml数据可能是这样子的。

<School>
  <Headmaster IsAssistant="false">
    <Name>LazyLeland</Name>
    <Sex>I</Sex>
    <Age>27</Age>
  </Headmaster>
  <Classes>
    <Class>
      <Teacher>
        <Name>June</Name>
        <Sex>O</Sex>
        <Age>30</Age>
      </Teacher>
      <Students>
        <Student>
          <Name>Student1</Name>
          <Sex>I</Sex>
          <Age>10</Age>
        </Student>
      </Students>
    </Class>
    <Class>
      <Teacher>
        <Name>Sam</Name>
        <Sex>I</Sex>
        <Age>32</Age>
      </Teacher>
      <Students>
        <Student>
          <Name>Student2</Name>
          <Sex>O</Sex>
          <Age>10</Age>
        </Student>
        <Student>
          <Name>Student3</Name>
          <Sex>I</Sex>
          <Age>10</Age>
        </Student>
        <Student>
          <Name>Student4</Name>
          <Sex>O</Sex>
          <Age>10</Age>
          <Skill>DB</Skill>
          <Skill>C#</Skill>
        </Student>
      </Students>
    </Class>
  </Classes>
</School>

注意xml中Student4的多个技能(Skill)没有使用Skills作为父节点,这是不规范的,但考虑到实际情况有可能数据是从已有的老系统中导出来,虽然不规范,但也需要正确地对其进行序列化。

接下来我们使用c#来定义数据的实体类。System.Xml.Serialization命名空间下提供了多个attribute(属性),通过这些attribute控制实体类的序列化过程。

Person.cs:

[Serializable]
[XmlRoot("Person")]
public class Person
{
	/// <summary>
	/// 需要定义无参数的构造函数,否则无法通过XmlSerializer进行序列化。
	/// </summary>
	public Person() { }

	public Person Parse(string aName, SexDef aSex, int aAge)
	{
		_name = aName;
		_sex = aSex;
		_age = aAge;

		return this;
	}

	private string _name = string.Empty;
	[XmlElement("Name")]
	public string Name
	{
		get
		{
			return _name;
		}

		set
		{
			_name = value;
		}
	}

	private SexDef _sex = SexDef.I;
	[XmlElement("Sex")]
	public SexDef Sex
	{
		get
		{
			return _sex;
		}

		set
		{
			_sex = value;
		}
	}

	private int _age;
	[XmlElement("Age")]
	public int Age
	{
		get
		{
			return _age;
		}

		set
		{
			_age = value;
		}
	}

	private List<Skill> _skills = new List<Skill>();
	[XmlElement("Skill")]
	public List<Skill> Skills
	{
		get
		{
			return _skills;
		}
	}

	[XmlIgnore()]
	public bool _isOlderThen30
	{
		get
		{
			return _age > 30;
		}
	}

	#region Nested Types

	[Serializable]
	public enum SexDef
	{ 
		O = 0x00,
		I = 0x01
	}

	public class Skill
	{
		/// <summary>
		/// 需要定义无参数的构造函数,否则无法通过XmlSerializer进行序列化。
		/// </summary>
		public Skill() { }

		public Skill Parse(string aName)
		{
			_name = aName;
			return this;
		}

		private string _name;
		[XmlText()]
		public string Name
		{
			get
			{
				return _name;
			}

			set
			{
				_name = value;
			}
		}
	}

	#endregion
}

[Serializable]
[XmlRoot("Headmaster")]
public class Headmaster : Person
{
	public Headmaster Parse(string aName, SexDef aSex, int aAge, bool aIsAssistant)
	{
		base.Parse(aName, aSex, aAge);

		_isAssistant = aIsAssistant;
		return this;
	}

	private bool _isAssistant;
	[XmlAttribute("IsAssistant")]
	public bool IsAssistant
	{
		get
		{
			return _isAssistant;
		}

		set
		{
			_isAssistant = value;
		}
	}
}

public class Teacher : Person { }
public class Student : Person { }

Class.cs

[Serializable]
public class Class
{
	private Teacher _teacher;
	[XmlElement("Teacher")]
	public Teacher Teacher
	{
		get
		{
			return _teacher;
		}

		set
		{
			_teacher = value;
		}
	}

	private List<Student> _students = new List<Student>();
	[XmlArray("Students")]
	[XmlArrayItem("Student")]
	public List<Student> Students
	{
		get
		{
			return _students;
		}
	}
}

School.cs

[Serializable]
[XmlRoot("School")]
public class School
{
	private Headmaster _headmaster;
	[XmlElement("Headmaster")]
	public Headmaster Headmaster
	{
		get
		{
			return _headmaster;
		}

		set
		{
			_headmaster = value;
		}
	}

	private List<Class> _classes = new List<Class>();
	[XmlArray("Classes")]
	[XmlArrayItem("Class")]
	public List<Class> Classes
	{
		get
		{
			return _classes;
		}
	}
}

上面的代码中用到了以下的attribute:

[Serializable]:用于标志这个类是可进行序列化的。注意此属性只能用于类定义上,另外类也可以通过实现System.Runtime.Serialization.ISerializable进行自定义序列化控制。

[XmlRoot]:用于定义xml根节点的节点名称。

[XmlElement]:用于定义类属性在序列化中对应节点的名称。

[XmlIgnore]:标志此属性不参与序列化。

[XmlArray]:通常与[XmlArrayItem]配合使用,定义数组的父节点名称与子节点名称。

此外,.net还提供了其它控制序列化的attribute,此例子不涉及,需要了解可进一步参考MSDN,一般情况下用这几个attribute就够了。

现在定义好了xml的格式与数据的实体类,接下来就是使用System.Xml.Serialization.XmlSerializer类进行序列化/反序列化了。

把对象序列化成xml的代码如下:

// 这里是实例化对象的代码,可以跳过。
Student student1 = new Student().Parse("Student1", Person.SexDef.I, 10) as Student;
Student student2 = new Student().Parse("Student2", Person.SexDef.O, 10) as Student;
Student student3 = new Student().Parse("Student3", Person.SexDef.I, 10) as Student;
Student student4 = new Student().Parse("Student4", Person.SexDef.O, 10) as Student;
student4.Skills.Add(new Person.Skill().Parse("DB"));
student4.Skills.Add(new Person.Skill().Parse("C#"));


Teacher teacher1 = new Teacher().Parse("June", Person.SexDef.O, 30) as Teacher;
Teacher teacher2 = new Teacher().Parse("Sam", Person.SexDef.I, 32) as Teacher;


Headmaster headmaster1 = new Headmaster().Parse("LazyLeland", Person.SexDef.I, 27, false);


Class class1 = new Class();
class1.Teacher = teacher1;
class1.Students.Add(student1);


Class class2 = new Class();
class2.Teacher = teacher2;
class2.Students.Add(student2);
class2.Students.Add(student3);
class2.Students.Add(student4);


School school = new School();
school.Headmaster = headmaster1;
school.Classes.Add(class1);
school.Classes.Add(class2);


// 序列化成xml的代码。
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(School));
xmlSerializer.Serialize(stringWriter, school);


//
return stringWriter.ToString();

根据xml反序列化成对象的代码如下:

//
System.IO.StringReader stringReader = new System.IO.StringReader(aXml);
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(School));


//
return xmlSerializer.Deserialize(stringReader) as School;




  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值