今天需要解析一个XML,这个XML和一般情况用.NET的序列化出来的格式不太一样。
我就又补习了一下。
分享一下学习成果吧。
示例代码下载:
http://download.csdn.net/detail/bdstjk/4028340
使用属性可以控制对象的 XML 序列化。
默认情况下,XML 元素名称由类或成员名称确定。在名为 Book 的简单类中,字段 ISBN 将生成 XML 元素标记 <ISBN>,如下面的示例所示。
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) 实现此目的。
1 |
public class TaxRates{ |
2 |
[XmlElement(ElementName = "TaxRate")] |
3 |
public decimal ReturnTaxRate; |
4 |
} |
XmlArrayAttribute 和 XmlArrayItemAttribute 属性旨在用于控制数组的序列化。使用这些属性可以控制元素名称、命名空间以及 XML 架构 (XSD) 数据类型(在万维网联合会 [www.w3.org] 文档“XML 架构第 2 部分:数据类型”中进行了定义)。此外,还可以指定数组所能包含的类型。
对于序列化数组时生成的封闭 XML 元素,其属性将由 XmlArrayAttribute 确定。例如,默认情况下,序列化下面的数组时,将会生成名为Employees 的 XML 元素。Employees 元素将包含在数组类型Employee 之后命名的一系列元素。
1 |
public class Group{ |
2 |
public Employee[] Employees; |
3 |
} |
4 |
public class Employee{ |
5 |
public string Name; |
6 |
} |
序列化实例可能如下所示。
1 |
<Group> |
2 |
<Employees> |
3 |
<Employee> |
4 |
<Name>Haley</Name> |
5 |
</Employee> |
6 |
</Employees > |
7 |
</Group> |
通过应用 XmlArrayAttribute,可以按照以下方式更改 XML 元素的名称。
1 |
public class Group{ |
2 |
[XmlArray("TeamMembers")] |
3 |
public Employee[] Employees; |
4 |
} |
生成的 XML 可能如下所示。
1 |
<Group> |
2 |
<TeamMembers> |
3 |
<Employee> |
4 |
<Name>Haley</Name> |
5 |
</Employee> |
6 |
</TeamMembers> |
另一方面,XmlArrayItemAttribute 可以控制如何序列化数组中包含的项。请注意,该属性将应用于返回数组的字段。
1 |
public class Group{ |
2 |
[XmlArrayItem("MemberName")] |
3 |
public Employee[] Employees; |
4 |
} |
生成的 XML 可能如下所示。
1 |
<Group> |
2 |
<Employees> |
3 |
<MemberName>Haley</MemberName> |
4 |
</Employees> |
5 |
</Group> |
序列化派生类
XmlArrayItemAttribute 的另一种用法是,允许序列化派生类。例如,可将派生自 Employee 的另一个名为Manager 的类添加至上一示例中。如果没有应用XmlArrayItemAttribute,代码将在运行时失败,原因是无法识别派生类类型。若要解决这个问题,每次为每个可接受类型(基类和派生类)设置 Type 属性 (Property) 时,需要应用该属性 (Attribute) 两次。
01 |
public class Group{ |
02 |
[XmlArrayItem(Type = typeof(Employee)), |
03 |
XmlArrayItem(Type = typeof(Manager))] |
04 |
public Employee[] Employees; |
05 |
} |
06 |
public class Employee{ |
07 |
public string Name; |
08 |
} |
09 |
public class Manager:Employee{ |
10 |
public int Level; |
11 |
} |
序列化实例可能如下所示。
01 |
<Group> |
02 |
<Employees> |
03 |
<Employee> |
04 |
<Name>Haley</Name> |
05 |
</Employee> |
06 |
<Employee xsi:type = "Manager"> |
07 |
<Name>Ann</Name> |
08 |
<Level>3</Level> |
09 |
<Employee> |
10 |
</Employees > |
11 |
</Group> |
将数组作为元素序列进行序列化
通过将 XmlElementAttribute 应用于返回数组的字段,还可以将该数组作为 XML 元素的平面序列进行序列化,如下所示。
1 |
public class Group{ |
2 |
[XmlElement] |
3 |
public Employee[] Employees; |
4 |
} |
序列化实例可能如下所示。
01 |
<Group> |
02 |
<Employees> |
03 |
<Name>Haley</Name> |
04 |
</Employees> |
05 |
<Employees> |
06 |
<Name>Noriko</Name> |
07 |
</Employees> |
08 |
<Employees> |
09 |
<Name>Marco</Name> |
10 |
</Employees> |
11 |
</Group> |
区别两种 XML 流的另一个方法是,使用 XML 架构定义工具,从编译好的代码生成 XML 架构 (XSD) 文档文件。没有将属性应用于字段时,架构会以下列方式描述元素。
<xs:element minOccurs="0" maxOccurs ="1" name="Employees" type="ArrayOfEmployee" /> |
|
将 XmlElementAttribute 应用于字段时,生成的架构会以下列方式描述元素。
<xs:element minOccurs="0" maxOccurs="unbounded" name="Employees" type="Employee" /> |
|
序列化 ArrayList
ArrayList 类可能包含各种不同对象的集合。因此,可以按照使用数组的类似方式使用 ArrayList。您可以创建返回单个ArrayList 的字段,而不用创建返回类型化对象的数组的字段。但是,与数组相同的是,必须将ArrayList 包含的对象的类型告知 XmlSerializer。为此,需要为该字段分配XmlElementAttribute 的多个实例,如下面的示例所示。
1 |
public class Group{ |
2 |
[XmlElement(Type = typeof(Employee)), |
3 |
XmlElement(Type = 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 同时应用于同一个类。
1 |
[XmlRoot("NewGroupName")] |
2 |
[XmlType("NewTypeName")] |
3 |
public class Group{ |
4 |
public Employee[] Employees; |
5 |
} |
如果对该类进行编译,并且使用 XML 架构定义工具生成其架构,可能会找到下面描述 Group 的 XML。
<xs:element name="NewGroupName" type="NewTypeName"> |
相比之下,如果是对该类的实例进行序列化,则只能在 XML 文档中找到 NewGroupName。
|
<NewGroupName> . . .</NewGroupName> |
最后来贴一个自己的XML解析实例
XML结构如下:
01 |
<?xml version="1.0" encoding="utf-8"?> |
02 |
<Root> |
03 |
<Person IDCard="610424199902230099" Name="小田雨" MedicalID="体检编号" Sex="男"Age="22" MedicalRecordDate ="2011-01-01" MedicalReportDate="2011-01-01" |
04 |
MedicalCount="体检次数" HospitalID="001" HospitalName="兴隆园医院" > |
05 |
<Results> |
06 |
<Result></Result> |
07 |
<Result></Result> |
08 |
<Result></Result> |
09 |
</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#代码如下:
代码有点多
001 |
using System; |
002 |
using System.Collections.Generic; |
003 |
using System.Linq; |
004 |
using System.Text; |
005 |
using System.Xml; |
006 |
using System.Xml.Serialization; |
007 |
008 |
using System.IO; |
009 |
010 |
namespace 天健接口 |
011 |
{ |
012 |
class Program |
013 |
{ |
014 |
static void Main(string[] args) |
015 |
{ |
016 |
Root r = new Root(); |
017 |
018 |
r.Person = new Person(); |
019 |
r.Person.IDCard = "22"; |
020 |
r.Person.Results = new List<string>(); |
021 |
r.Person.Results.Add("1"); |
022 |
r.Person.Results.Add("1"); |
023 |
r.Person.Results.Add("1"); |
024 |
r.Person.Suggestions = new List<string>(); |
025 |
r.Person.Suggestions.Add("2"); |
026 |
r.Person.Suggestions.Add("2"); |
027 |
r.Person.Suggestions.Add("2"); |
028 |
029 |
r.MedicalItems = new List<MedicalSub>(); |
030 |
MedicalSub ms = new MedicalSub(); |
031 |
ms.ID = "ss"; |
032 |
ms.Name="de"; |
033 |
ms.MedicalType = new MedicalType(); |
034 |
ms.MedicalType.ID = "wa"; |
035 |
ms.MedicalType.Name = "s"; |
036 |
ms.MedicalType.MedicalDoc= "qa"; |
037 |
ms.MedicalType.MedicalDate = "2010-5-5"; |
038 |
ms.MedicalType.Item = new List<Item>(); |
039 |
Item it = new Item(); |
040 |
it.ID = "f"; |
041 |
it.Name = "s"; |
042 |
it.Results = "s"; |
043 |
ms.MedicalType.Item.Add(it); |
044 |
ms.MedicalType.Item.Add(it); |
045 |
r.MedicalItems.Add(ms); |
046 |
r.MedicalItems.Add(ms); |
047 |
048 |
Console.WriteLine("序列化成功……"); |
049 |
Console.WriteLine(XmlSerialize.SerializeXML<Root>(r)); |
050 |
|
051 |
|
052 |
053 |
} |
054 |
} |
055 |
056 |
[Serializable] |
057 |
public class Root |
058 |
{ |
059 |
//[XmlElement] |
060 |
public Person Person; |
061 |
062 |
public List<MedicalSub> MedicalItems; |
063 |
} |
064 |
065 |
[Serializable] |
066 |
public class Person |
067 |
{ |
068 |
[XmlAttribute] |
069 |
public string IDCard; |
070 |
071 |
[XmlAttribute] |
072 |
public string Name; |
073 |
074 |
[XmlAttribute] |
075 |
public string MedicalID; |
076 |
077 |
[XmlAttribute] |
078 |
public string Sex; |
079 |
080 |
[XmlAttribute] |
081 |
public string Age; |
082 |
083 |
[XmlAttribute] |
084 |
public string MedicalRecordDate; |
085 |
086 |
[XmlAttribute] |
087 |
public string MedicalReportDate; |
088 |
089 |
[XmlAttribute] |
090 |
public string MedicalCount; |
091 |
092 |
[XmlAttribute] |
093 |
public string HospitalID; |
094 |
095 |
[XmlAttribute] |
096 |
public string HospitalName; |
097 |
098 |
[XmlArrayItem("Result")] |
099 |
public List<string> Results; |
100 |
101 |
[XmlArrayItem("Conclusion")] |
102 |
public List<string> Conclusions; |
103 |
104 |
[XmlArrayItem("Suggestion")] |
105 |
public List<string> Suggestions; |
106 |
107 |
public String Health; |
108 |
} |
109 |
110 |
[Serializable] |
111 |
public class MedicalSub |
112 |
{ |
113 |
[XmlAttribute] |
114 |
public string ID; |
115 |
116 |
[XmlAttribute] |
117 |
public string Name; |
118 |
119 |
public MedicalType MedicalType; |
120 |
121 |
} |
122 |
123 |
[Serializable] |
124 |
public class MedicalType |
125 |
{ |
126 |
[XmlAttribute] |
127 |
public string ID; |
128 |
129 |
[XmlAttribute] |
130 |
public string Name; |
131 |
132 |
[XmlAttribute] |
133 |
public string MedicalDoc; |
134 |
135 |
[XmlAttribute] |
136 |
public string MedicalDate; |
137 |
138 |
[XmlElement] |
139 |
public List<Item> Item; |
140 |
} |
141 |
142 |
public class Item |
143 |
{ |
144 |
[XmlAttribute] |
145 |
public string ID; |
146 |
147 |
[XmlAttribute] |
148 |
public string Name; |
149 |
150 |
[XmlAttribute] |
151 |
public string Unit; |
152 |
153 |
[XmlAttribute] |
154 |
public string Parameters; |
155 |
156 |
157 |
public string Results; |
158 |
159 |
public string Value; |
160 |
161 |
public string Disease; |
162 |
163 |
public string MedicalBodyPart; |
164 |
165 |
public string MedicalImage; |
166 |
167 |
public string Conclusion; |
168 |
169 |
170 |
} |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
public class XmlSerialize |
178 |
{ |
179 |
/// <summary> |
180 |
/// 反序列化XML为类实例 |
181 |
/// </summary> |
182 |
/// <typeparam name="T"></typeparam> |
183 |
/// <param name="xmlObj"></param> |
184 |
/// <returns></returns> |
185 |
public static T DeserializeXML<T>(string xmlObj) |
186 |
{ |
187 |
XmlSerializer serializer = new XmlSerializer(typeof(T)); |
188 |
using (StringReader reader = new StringReader(xmlObj)) |
189 |
{ |
190 |
return (T)serializer.Deserialize(reader); |
191 |
} |
192 |
} |
193 |
194 |
/// <summary> |
195 |
/// 序列化类实例为XML |
196 |
/// </summary> |
197 |
/// <typeparam name="T"></typeparam> |
198 |
/// <param name="obj"></param> |
199 |
/// <returns></returns> |
200 |
public static string SerializeXML<T>(T obj) |
201 |
{ |
202 |
using (StringWriter writer = new StringWriter()) |
203 |
{ |
204 |
new XmlSerializer(obj.GetType()).Serialize((TextWriter)writer, obj); |
205 |
return writer.ToString(); |
206 |
} |
207 |
} |
208 |
} |
209 |
210 |
211 |
} |
来自:http://blog.csdn.net/bdstjk/article/details/7210742
浙公网安备 33010602011771号