在C#中使用屬性控制 XML 序列化來解析XML
今天需要解析一個XML,這個XML和一般情況用.NET的序列化出來的格式不太一樣。
我就又補習了一下。
分享一下學習成果吧。
示例代碼下載:
http://download.csdn.net/detail/bdstjk/4028340
使用屬性可以控制對象的 XML 序列化。
默認情況下,XML 元素名稱由類或成員名稱確定。在名為 Book
的簡單類中,字段 ISBN
將生成 XML 元素標記 <ISBN>,如下面的示例所示。
public class Book { public string ISBN; } // When an instance of the Book class is serialized, it might // produce this XML: // <ISBN>1234567890</ISBN>.
若要重新命名元素,可以更改這種默認行為。下面的代碼演示屬性 (Attribute) 如何通過設置 XmlElementAttribute 的 ElementName 屬性 (Property) 實現此目的。
public class TaxRates{ [XmlElement(ElementName = "TaxRate")] public decimal ReturnTaxRate; }
XmlArrayAttribute 和 XmlArrayItemAttribute 屬性旨在用于控制數組的序列化。使用這些屬性可以控制元素名稱、命名空間以及 XML 架構 (XSD) 數據類型(在萬維網聯合會 [www.w3.org] 文檔“XML 架構第 2 部分:數據類型”中進行了定義)。此外,還可以指定數組所能包含的類型。
對于序列化數組時生成的封閉 XML 元素,其屬性將由 XmlArrayAttribute 確定。例如,默認情況下,序列化下面的數組時,將會生成名為Employees
的 XML 元素。Employees
元素將包含在數組類型Employee
之后命名的一系列元素。
public class Group{ public Employee[] Employees; } public class Employee{ public string Name; }
序列化實例可能如下所示。
<Group> <Employees> <Employee> <Name>Haley</Name> </Employee> </Employees > </Group>
通過應用 XmlArrayAttribute,可以按照以下方式更改 XML 元素的名稱。
public class Group{ [XmlArray("TeamMembers")] public Employee[] Employees; }
生成的 XML 可能如下所示。
<Group> <TeamMembers> <Employee> <Name>Haley</Name> </Employee> </TeamMembers>
另一方面,XmlArrayItemAttribute 可以控制如何序列化數組中包含的項。請注意,該屬性將應用于返回數組的字段。
public class Group{ [XmlArrayItem("MemberName")] public Employee[] Employees; }
生成的 XML 可能如下所示。
<Group> <Employees> <MemberName>Haley</MemberName> </Employees> </Group>
序列化派生類
XmlArrayItemAttribute 的另一種用法是,允許序列化派生類。例如,可將派生自 Employee
的另一個名為Manager
的類添加至上一示例中。如果沒有應用XmlArrayItemAttribute,代碼將在運行時失敗,原因是無法識別派生類類型。若要解決這個問題,每次為每個可接受類型(基類和派生類)設置 Type 屬性 (Property) 時,需要應用該屬性 (Attribute) 兩次。
public class Group{ [XmlArrayItem(Type = typeof(Employee)), XmlArrayItem(Type = typeof(Manager))] public Employee[] Employees; } public class Employee{ public string Name; } public class Manager:Employee{ public int Level; }
序列化實例可能如下所示。
<Group> <Employees> <Employee> <Name>Haley</Name> </Employee> <Employee xsi:type = "Manager"> <Name>Ann</Name> <Level>3</Level> <Employee> </Employees > </Group>
將數組作為元素序列進行序列化
通過將 XmlElementAttribute 應用于返回數組的字段,還可以將該數組作為 XML 元素的平面序列進行序列化,如下所示。
public class Group{ [XmlElement] public Employee[] Employees; }
序列化實例可能如下所示。
<Group> <Employees> <Name>Haley</Name> </Employees> <Employees> <Name>Noriko</Name> </Employees> <Employees> <Name>Marco</Name> </Employees> </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 的多個實例,如下面的示例所示。
public class Group{ [XmlElement(Type = typeof(Employee)), XmlElement(Type = typeof(Manager))] public ArrayList Info; }
使用 XmlRootAttribute 和 XmlTypeAttribute 控制類的序列化
能且只能應用于一個類的屬性有下面兩種:XmlRootAttribute 和 XmlTypeAttribute。這兩種屬性非常相似。XmlRootAttribute 只能應用于一個類:序列化時,該類表示 XML 文檔的開始和結束元素,也就是根元素。另一方面,XmlTypeAttribute 可以應用于任何一個類,包括根類。
例如,在上面的示例中,Group
類就是根類,而其所有的公共字段和屬性變成 XML 文檔中的 XML 元素。因此,只能有一個根類。通過應用XmlRootAttribute,可以控制XmlSerializer 所生成的 XML 流。例如,可以更改元素名稱和命名空間。
使用 XmlTypeAttribute 可以控制所生成 XML 的架構。需要通過 XML Web services 發布架構時,這項功能很有用。下面的示例將XmlTypeAttribute 和XmlRootAttribute 同時應用于同一個類。
[XmlRoot("NewGroupName")] [XmlType("NewTypeName")] public class Group{ public Employee[] Employees; }
如果對該類進行編譯,并且使用 XML 架構定義工具生成其架構,可能會找到下面描述 Group
的 XML。
<xs:element name="NewGroupName" type="NewTypeName"> |
相比之下,如果是對該類的實例進行序列化,則只能在 XML 文檔中找到 NewGroupName
。
<NewGroupName> . . .</NewGroupName> |
最后來貼一個自己的XML解析實例
XML結構如下:
<?xml version="1.0" encoding="utf-8"?> <Root> <Person IDCard="610424199902230099" Name="小田雨" MedicalID="體檢編號" Sex="男" Age="22" MedicalRecordDate ="2011-01-01" MedicalReportDate="2011-01-01" MedicalCount="體檢次數" HospitalID="001" HospitalName="興隆園醫院" > <Results> <Result></Result> <Result></Result> <Result></Result> </Results> <Conclusions> <Conclusion></Conclusion> <Conclusion></Conclusion> <Conclusion></Conclusion> </Conclusions> <Suggestions> <Suggestion></Suggestion> <Suggestion></Suggestion> <Suggestion></Suggestion> </Suggestions> <Health> 為空(預留)</Health> </Person> <MedicalItems> <MedicalSub ID ="0001" Name="化學檢查" > <MedicalType ID ="0001001" Name="血常規" MedicalDoc="體檢醫師名字" MedicalDate="2011-02-13"> <Item ID="000100010001" Name="白細胞" Unit="G/L" Parameters="3.7--10.0" > <Results>H==高,L=低,N=正常</Results> <Value>11.1</Value> <Disease></Disease> <MedicalBodyPart> </MedicalBodyPart> <MedicalImage> </MedicalImage> <Conclusion ></Conclusion> </Item> <Item ID="000100010002" Name="紅細胞" Unit="G/L" Parameters="3.7--10.0"> <Results>H==高,L=低,N=正常</Results> <Value>11.1</Value> <Disease></Disease> <MedicalBodyPart> </MedicalBodyPart> <MedicalImage> </MedicalImage> <Conclusion ></Conclusion> </Item> </MedicalType> </MedicalSub> <MedicalSub ID ="0002" Name="物理檢查" > <MedicalType ID ="0002001" Name="B超" MedicalDoc="體檢醫師名字" MedicalDate="2011-02-13"> <Item ID="000200010001" Name="胸部B超" Unit=" " Parameters=""> <Results>A=異常,N=正常</Results> <Value></Value> <Disease>病種,未見異常</Disease> <MedicalBodyPart>檢查部位:胸部</MedicalBodyPart> <MedicalImage>影像所見</MedicalImage> <Conclusion >檢查結論</Conclusion> </Item> <Item ID="000200010002" Name="腹部B超" Unit=" " Parameters=""> <Results>A=異常,N=正常</Results> <Value></Value> <Disease>病種,未見異常</Disease> <MedicalBodyPart>檢查部位:腹部</MedicalBodyPart> <MedicalImage>影像所見</MedicalImage> <Conclusion >檢查結論</Conclusion> </Item> </MedicalType> </MedicalSub> <MedicalSub ID ="0005" Name="五官科" > <MedicalType ID ="0005001" Name="眼科" MedicalDoc="體檢醫師名字" MedicalDate="2011-02-13"> <Item ID="000500010001" Name="視力/右" Unit=" " Parameters="1.0-1.5"> <Results>A=異常,N=正常</Results> <Value>1.5</Value> <Disease>病種,未見異常</Disease> <MedicalBodyPart>檢查部位</MedicalBodyPart> <MedicalImage>影像所見</MedicalImage> <Conclusion >檢查結論</Conclusion> </Item> <Item ID="000500010002" Name="矯正視力/右" Unit=" " Parameters="1.0-1.5"> <Results>A=異常,N=正常</Results> <Value>0.8</Value> <Disease>病種,未見異常</Disease> <MedicalBodyPart>檢查部位</MedicalBodyPart> <MedicalImage>影像所見</MedicalImage> <Conclusion >檢查結論</Conclusion> </Item> </MedicalType> </MedicalSub> </MedicalItems> </Root>
C#代碼如下:
代碼有點多
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Xml.Serialization; using System.IO; namespace 天健接口 { class Program { static void Main(string[] args) { Root r = new Root(); r.Person = new Person(); r.Person.IDCard = "22"; r.Person.Results = new List<string>(); r.Person.Results.Add("1"); r.Person.Results.Add("1"); r.Person.Results.Add("1"); r.Person.Suggestions = new List<string>(); r.Person.Suggestions.Add("2"); r.Person.Suggestions.Add("2"); r.Person.Suggestions.Add("2"); r.MedicalItems = new List<MedicalSub>(); MedicalSub ms = new MedicalSub(); ms.ID = "ss"; ms.Name="de"; ms.MedicalType = new MedicalType(); ms.MedicalType.ID = "wa"; ms.MedicalType.Name = "s"; ms.MedicalType.MedicalDoc= "qa"; ms.MedicalType.MedicalDate = "2010-5-5"; ms.MedicalType.Item = new List<Item>(); Item it = new Item(); it.ID = "f"; it.Name = "s"; it.Results = "s"; ms.MedicalType.Item.Add(it); ms.MedicalType.Item.Add(it); r.MedicalItems.Add(ms); r.MedicalItems.Add(ms); Console.WriteLine("序列化成功……"); Console.WriteLine(XmlSerialize.SerializeXML<Root>(r)); } } [Serializable] public class Root { //[XmlElement] public Person Person; public List<MedicalSub> MedicalItems; } [Serializable] public class Person { [XmlAttribute] public string IDCard; [XmlAttribute] public string Name; [XmlAttribute] public string MedicalID; [XmlAttribute] public string Sex; [XmlAttribute] public string Age; [XmlAttribute] public string MedicalRecordDate; [XmlAttribute] public string MedicalReportDate; [XmlAttribute] public string MedicalCount; [XmlAttribute] public string HospitalID; [XmlAttribute] public string HospitalName; [XmlArrayItem("Result")] public List<string> Results; [XmlArrayItem("Conclusion")] public List<string> Conclusions; [XmlArrayItem("Suggestion")] public List<string> Suggestions; public String Health; } [Serializable] public class MedicalSub { [XmlAttribute] public string ID; [XmlAttribute] public string Name; public MedicalType MedicalType; } [Serializable] public class MedicalType { [XmlAttribute] public string ID; [XmlAttribute] public string Name; [XmlAttribute] public string MedicalDoc; [XmlAttribute] public string MedicalDate; [XmlElement] public List<Item> Item; } public class Item { [XmlAttribute] public string ID; [XmlAttribute] public string Name; [XmlAttribute] public string Unit; [XmlAttribute] public string Parameters; public string Results; public string Value; public string Disease; public string MedicalBodyPart; public string MedicalImage; public string Conclusion; } public class XmlSerialize { /// <summary> /// 反序列化XML為類實例 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="xmlObj"></param> /// <returns></returns> public static T DeserializeXML<T>(string xmlObj) { XmlSerializer serializer = new XmlSerializer(typeof(T)); using (StringReader reader = new StringReader(xmlObj)) { return (T)serializer.Deserialize(reader); } } /// <summary> /// 序列化類實例為XML /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <returns></returns> public static string SerializeXML<T>(T obj) { using (StringWriter writer = new StringWriter()) { new XmlSerializer(obj.GetType()).Serialize((TextWriter)writer, obj); return writer.ToString(); } } } }
來自:http://blog.csdn.net/bdstjk/article/details/7210742