今天需要解析一个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