使用属性可以控制对象的 XML 序列化。
默认情况下,XML 元素名称由类或成员名称确定。在名为 Book
的简单类中,字段 ISBN
将生成 XML 元素标记 <ISBN>,如下面的示例所示。
[csharp] view plain copy
1. public class Book
2. {
3. public string ISBN;
4. }
5. // When an instance of the Book class is serialized, it might
6. // produce this XML:
7. // <ISBN>1234567890</ISBN>.
若要重新命名元素,可以更改这种默认行为。下面的代码演示属性 (Attribute) 如何通过设置 XmlElementAttribute 的 ElementName 属性 (Property) 实现此目的。
[csharp] view plain copy
1. public class TaxRates{
2. "TaxRate")]
3. public decimal ReturnTaxRate;
4. }
XmlArrayAttribute 和 XmlArrayItemAttribute 属性旨在用于控制数组的序列化。使用这些属性可以控制元素名称、命名空间以及 XML 架构 (XSD) 数据类型(在万维网联合会 [www.w3.org] 文档“XML 架构第 2 部分:数据类型”中进行了定义)。此外,还可以指定数组所能包含的类型。
对于序列化数组时生成的封闭 XML 元素,其属性将由 XmlArrayAttribute 确定。例如,默认情况下,序列化下面的数组时,将会生成名为Employees
的 XML 元素。Employees
元素将包含在数组类型Employee
之后命名的一系列元素。
[csharp] view plain copy
1. public class Group{
2. public Employee[] Employees;
3. }
4. public class Employee{
5. public string Name;
6. }
序列化实例可能如下所示。
[html] view plain copy
1. <Group>
2. <Employees>
3. <Employee>
4. <Name>Haley</Name>
5. </Employee>
6. </Employees >
7. </Group>
通过应用 XmlArrayAttribute,可以按照以下方式更改 XML 元素的名称。
[csharp] view plain copy
1. public class Group{
2. "TeamMembers")]
3. public Employee[] Employees;
4. }
生成的 XML 可能如下所示。
[html] view plain copy
1. <Group>
2. <TeamMembers>
3. <Employee>
4. <Name>Haley</Name>
5. </Employee>
6. </TeamMembers>
另一方面,XmlArrayItemAttribute 可以控制如何序列化数组中包含的项。请注意,该属性将应用于返回数组的字段。
[csharp] view plain copy
1. public class Group{
2. "MemberName")]
3. public Employee[] Employees;
4. }
生成的 XML 可能如下所示。
[html] view plain copy
1. <Group>
2. <Employees>
3. <MemberName>Haley</MemberName>
4. </Employees>
5. </Group>
序列化派生类
XmlArrayItemAttribute 的另一种用法是,允许序列化派生类。例如,可将派生自 Employee
的另一个名为Manager
的类添加至上一示例中。如果没有应用XmlArrayItemAttribute,代码将在运行时失败,原因是无法识别派生类类型。若要解决这个问题,每次为每个可接受类型(基类和派生类)设置 Type 属性 (Property) 时,需要应用该属性 (Attribute) 两次。
[csharp] view plain copy
1. public class Group{
2. typeof(Employee)),
3. typeof(Manager))]
4. public Employee[] Employees;
5. }
6. public class Employee{
7. public string Name;
8. }
9. public class Manager:Employee{
10. public int Level;
11. }
序列化实例可能如下所示。
[html] view plain copy
1. <Group>
2. <Employees>
3. <Employee>
4. <Name>Haley</Name>
5. </Employee>
6. <Employee xsi:type = "Manager">
7. <Name>Ann</Name>
8. <Level>3</Level>
9. <Employee>
10. </Employees >
11. </Group>
将数组作为元素序列进行序列化
通过将 XmlElementAttribute 应用于返回数组的字段,还可以将该数组作为 XML 元素的平面序列进行序列化,如下所示。
[csharp] view plain copy
1. public class Group{
2. [XmlElement]
3. public Employee[] Employees;
4. }
序列化实例可能如下所示。
[html] view plain copy
1. <Group>
2. <Employees>
3. <Name>Haley</Name>
4. </Employees>
5. <Employees>
6. <Name>Noriko</Name>
7. </Employees>
8. <Employees>
9. <Name>Marco</Name>
10. </Employees>
11. </Group>
区别两种 XML 流的另一个方法是,使用 XML 架构定义工具,从编译好的代码生成 XML 架构 (XSD) 文档文件。没有将属性应用于字段时,架构会以下列方式描述元素。
| |
|
将 XmlElementAttribute 应用于字段时,生成的架构会以下列方式描述元素。
| |
|
序列化 ArrayList
ArrayList 类可能包含各种不同对象的集合。因此,可以按照使用数组的类似方式使用 ArrayList。您可以创建返回单个ArrayList 的字段,而不用创建返回类型化对象的数组的字段。但是,与数组相同的是,必须将ArrayList 包含的对象的类型告知 XmlSerializer。为此,需要为该字段分配XmlElementAttribute 的多个实例,如下面的示例所示。
[csharp] view plain copy
1. public class Group{
2. typeof(Employee)),
3. typeof(Manager))]
4. public ArrayList Info;
5. }
使用 XmlRootAttribute 和 XmlTypeAttribute 控制类的序列化
能且只能应用于一个类的属性有下面两种:XmlRootAttribute 和 XmlTypeAttribute。这两种属性非常相似。XmlRootAttribute 只能应用于一个类:序列化时,该类表示 XML 文档的开始和结束元素,也就是根元素。另一方面,XmlTypeAttribute 可以应用于任何一个类,包括根类。
例如,在上面的示例中,Group
类就是根类,而其所有的公共字段和属性变成 XML 文档中的 XML 元素。因此,只能有一个根类。通过应用XmlRootAttribute,可以控制XmlSerializer 所生成的 XML 流。例如,可以更改元素名称和命名空间。
使用 XmlTypeAttribute 可以控制所生成 XML 的架构。需要通过 XML Web services 发布架构时,这项功能很有用。下面的示例将XmlTypeAttribute 和XmlRootAttribute 同时应用于同一个类。
[csharp] view plain copy
1. [XmlRoot("NewGroupName")]
2. [XmlType("NewTypeName")]
3. public class Group{
4. public Employee[] Employees;
5. }
如果对该类进行编译,并且使用 XML 架构定义工具生成其架构,可能会找到下面描述 Group
的 XML。
|
相比之下,如果是对该类的实例进行序列化,则只能在 XML 文档中找到 NewGroupName
。
|
XML解析实例
XML结构如下:
[html] view plain copy
1. <?xml version="1.0" encoding="utf-8"?>
2. <Root>
3. <Person IDCard="610424199902230099" Name="小田雨" MedicalID="体检编号" Sex="男" Age="22" MedicalRecordDate ="2011-01-01" MedicalReportDate="2011-01-01"
4. MedicalCount="体检次数" HospitalID="001" HospitalName="兴隆园医院" >
5. <Results>
6. <Result></Result>
7. <Result></Result>
8. <Result></Result>
9. </Results>
10. <Conclusions>
11. <Conclusion></Conclusion>
12. <Conclusion></Conclusion>
13. <Conclusion></Conclusion>
14. </Conclusions>
15. <Suggestions>
16. <Suggestion></Suggestion>
17. <Suggestion></Suggestion>
18. <Suggestion></Suggestion>
19. </Suggestions>
20. <Health> 为空(预留)</Health>
21. </Person>
22.
23. <MedicalItems>
24. <MedicalSub ID ="0001" Name="化学检查" >
25. <MedicalType ID ="0001001" Name="血常规" MedicalDoc="体检医师名字" MedicalDate="2011-02-13">
26.
27. <Item ID="000100010001" Name="白细胞" Unit="G/L" Parameters="3.7--10.0" >
28. <Results>H==高,L=低,N=正常</Results>
29. <Value>11.1</Value>
30. <Disease></Disease>
31. <MedicalBodyPart> </MedicalBodyPart>
32. <MedicalImage> </MedicalImage>
33. <Conclusion ></Conclusion>
34. </Item>
35. <Item ID="000100010002" Name="红细胞" Unit="G/L" Parameters="3.7--10.0">
36. <Results>H==高,L=低,N=正常</Results>
37. <Value>11.1</Value>
38. <Disease></Disease>
39. <MedicalBodyPart> </MedicalBodyPart>
40. <MedicalImage> </MedicalImage>
41. <Conclusion ></Conclusion>
42. </Item>
43. </MedicalType>
44. </MedicalSub>
45. <MedicalSub ID ="0002" Name="物理检查" >
46. <MedicalType ID ="0002001" Name="B超" MedicalDoc="体检医师名字" MedicalDate="2011-02-13">
47. <Item ID="000200010001" Name="胸部B超" Unit=" " Parameters="">
48. <Results>A=异常,N=正常</Results>
49. <Value></Value>
50. <Disease>病种,未见异常</Disease>
51. <MedicalBodyPart>检查部位:胸部</MedicalBodyPart>
52. <MedicalImage>影像所见</MedicalImage>
53. <Conclusion >检查结论</Conclusion>
54. </Item>
55. <Item ID="000200010002" Name="腹部B超" Unit=" " Parameters="">
56. <Results>A=异常,N=正常</Results>
57. <Value></Value>
58. <Disease>病种,未见异常</Disease>
59. <MedicalBodyPart>检查部位:腹部</MedicalBodyPart>
60. <MedicalImage>影像所见</MedicalImage>
61. <Conclusion >检查结论</Conclusion>
62. </Item>
63. </MedicalType>
64.
65. </MedicalSub>
66. <MedicalSub ID ="0005" Name="五官科" >
67. <MedicalType ID ="0005001" Name="眼科" MedicalDoc="体检医师名字" MedicalDate="2011-02-13">
68. <Item ID="000500010001" Name="视力/右" Unit=" " Parameters="1.0-1.5">
69. <Results>A=异常,N=正常</Results>
70. <Value>1.5</Value>
71. <Disease>病种,未见异常</Disease>
72. <MedicalBodyPart>检查部位</MedicalBodyPart>
73. <MedicalImage>影像所见</MedicalImage>
74. <Conclusion >检查结论</Conclusion>
75. </Item>
76. <Item ID="000500010002" Name="矫正视力/右" Unit=" " Parameters="1.0-1.5">
77. <Results>A=异常,N=正常</Results>
78. <Value>0.8</Value>
79. <Disease>病种,未见异常</Disease>
80. <MedicalBodyPart>检查部位</MedicalBodyPart>
81. <MedicalImage>影像所见</MedicalImage>
82. <Conclusion >检查结论</Conclusion>
83. </Item>
84. </MedicalType>
85.
86. </MedicalSub>
87. </MedicalItems>
88. </Root>
C#代码如下:
[csharp] view plain copy
1. using System;
2. using System.Collections.Generic;
3. using System.Linq;
4. using System.Text;
5. using System.Xml;
6. using System.Xml.Serialization;
7.
8. using System.IO;
9.
10. namespace 天健接口
11. {
12. class Program
13. {
14. static void Main(string[] args)
15. {
16. new Root();
17.
18. new Person();
19. "22";
20. new List<string>();
21. "1");
22. "1");
23. "1");
24. new List<string>();
25. "2");
26. "2");
27. "2");
28.
29. new List<MedicalSub>();
30. new MedicalSub();
31. "ss";
32. "de";
33. new MedicalType();
34. "wa";
35. "s";
36. "qa";
37. "2010-5-5";
38. new List<Item>();
39. new Item();
40. "f";
41. "s";
42. "s";
43. ms.MedicalType.Item.Add(it);
44. ms.MedicalType.Item.Add(it);
45. r.MedicalItems.Add(ms);
46. r.MedicalItems.Add(ms);
47.
48. "序列化成功……");
49. Console.WriteLine(XmlSerialize.SerializeXML<Root>(r));
50. }
51. }
52.
53. [Serializable]
54. public class Root
55. {
56. //[XmlElement]
57. public Person Person;
58.
59. public List<MedicalSub> MedicalItems;
60. }
61.
62. [Serializable]
63. public class Person
64. {
65. [XmlAttribute]
66. public string IDCard;
67.
68. [XmlAttribute]
69. public string Name;
70.
71. [XmlAttribute]
72. public string MedicalID;
73.
74. [XmlAttribute]
75. public string Sex;
76.
77. [XmlAttribute]
78. public string Age;
79.
80. [XmlAttribute]
81. public string MedicalRecordDate;
82.
83. [XmlAttribute]
84. public string MedicalReportDate;
85.
86. [XmlAttribute]
87. public string MedicalCount;
88.
89. [XmlAttribute]
90. public string HospitalID;
91.
92. [XmlAttribute]
93. public string HospitalName;
94.
95. "Result")]
96. public List<string> Results;
97.
98. "Conclusion")]
99. public List<string> Conclusions;
100.
101. "Suggestion")]
102. public List<string> Suggestions;
103.
104. public String Health;
105. }
106.
107. [Serializable]
108. public class MedicalSub
109. {
110. [XmlAttribute]
111. public string ID;
112.
113. [XmlAttribute]
114. public string Name;
115.
116. public MedicalType MedicalType;
117. }
118.
119. [Serializable]
120. public class MedicalType
121. {
122. [XmlAttribute]
123. public string ID;
124.
125. [XmlAttribute]
126. public string Name;
127.
128. [XmlAttribute]
129. public string MedicalDoc;
130.
131. [XmlAttribute]
132. public string MedicalDate;
133.
134. [XmlElement]
135. public List<Item> Item;
136. }
137.
138. public class Item
139. {
140. [XmlAttribute]
141. public string ID;
142.
143. [XmlAttribute]
144. public string Name;
145.
146. [XmlAttribute]
147. public string Unit;
148.
149. [XmlAttribute]
150. public string Parameters;
151.
152.
153. public string Results;
154.
155. public string Value;
156.
157. public string Disease;
158.
159. public string MedicalBodyPart;
160.
161. public string MedicalImage;
162.
163. public string Conclusion;
164.
165.
166. }
167.
168. public class XmlSerialize
169. {
170. /// <summary>
171. /// 反序列化XML为类实例
172. /// </summary>
173. /// <typeparam name="T"></typeparam>
174. /// <param name="xmlObj"></param>
175. /// <returns></returns>
176. public static T DeserializeXML<T>(string xmlObj)
177. {
178. new XmlSerializer(typeof(T));
179. using (StringReader reader = new StringReader(xmlObj))
180. {
181. return (T)serializer.Deserialize(reader);
182. }
183. }
184.
185. /// <summary>
186. /// 序列化类实例为XML
187. /// </summary>
188. /// <typeparam name="T"></typeparam>
189. /// <param name="obj"></param>
190. /// <returns></returns>
191. public static string SerializeXML<T>(T obj)
192. {
193. using (StringWriter writer = new StringWriter())
194. {
195. new XmlSerializer(obj.GetType()).Serialize((TextWriter)writer, obj);
196. return writer.ToString();
197. }
198. }
199. }
200. }