C#.NET解析XML(使用属性控制 XML 序列化)

今天需要解析一个XML,这个XML和一般情况用.NET的序列化出来的格式不太一样。

我就又补习了一下。

分享一下学习成果吧。

示例代码下载:

http://download.csdn.net/detail/bdstjk/4028340

先给大家看看基础知识吧,后面再给大家贴一个复杂实例

 

使用属性可以控制对象的 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.     [XmlElement(ElementName = "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.     [XmlArray("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.     [XmlArrayItem("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.     [XmlArrayItem(Type = typeof(Employee)),  
  3.     XmlArrayItem(Type = 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) 文档文件。没有将属性应用于字段时,架构会以下列方式描述元素。

 
<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 的多个实例,如下面的示例所示。

[csharp]  view plain  copy
  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 同时应用于同一个类。

[csharp]  view plain  copy
  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结构如下:

[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.             Root r = new Root();  
  17.   
  18.             r.Person = new Person();  
  19.             r.Person.IDCard = "22";  
  20.             r.Person.Results = new List<string>();  
  21.             r.Person.Results.Add("1");  
  22.             r.Person.Results.Add("1");  
  23.             r.Person.Results.Add("1");  
  24.             r.Person.Suggestions = new List<string>();  
  25.             r.Person.Suggestions.Add("2");  
  26.             r.Person.Suggestions.Add("2");  
  27.             r.Person.Suggestions.Add("2");  
  28.   
  29.             r.MedicalItems = new List<MedicalSub>();  
  30.             MedicalSub ms = new MedicalSub();  
  31.             ms.ID = "ss";  
  32.             ms.Name="de";  
  33.             ms.MedicalType = new MedicalType();  
  34.             ms.MedicalType.ID = "wa";  
  35.             ms.MedicalType.Name = "s";  
  36.             ms.MedicalType.MedicalDoc= "qa";  
  37.             ms.MedicalType.MedicalDate = "2010-5-5";  
  38.             ms.MedicalType.Item = new List<Item>();  
  39.             Item it = new Item();  
  40.             it.ID = "f";  
  41.             it.Name = "s";  
  42.             it.Results = "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.             Console.WriteLine("序列化成功……");  
  49.             Console.WriteLine(XmlSerialize.SerializeXML<Root>(r));  
  50.               
  51.              
  52.   
  53.         }  
  54.     }  
  55.   
  56.     [Serializable]  
  57.     public class Root  
  58.     {  
  59.         //[XmlElement]  
  60.         public Person Person;  
  61.   
  62.         public List<MedicalSub> MedicalItems;  
  63.     }  
  64.   
  65.     [Serializable]  
  66.     public class Person  
  67.     {  
  68.         [XmlAttribute]  
  69.         public string IDCard;  
  70.   
  71.         [XmlAttribute]  
  72.         public string Name;  
  73.   
  74.         [XmlAttribute]  
  75.         public string MedicalID;  
  76.   
  77.         [XmlAttribute]  
  78.         public string Sex;  
  79.   
  80.         [XmlAttribute]  
  81.         public string Age;  
  82.   
  83.         [XmlAttribute]  
  84.         public string MedicalRecordDate;  
  85.   
  86.         [XmlAttribute]  
  87.         public string MedicalReportDate;  
  88.   
  89.         [XmlAttribute]  
  90.         public string MedicalCount;  
  91.   
  92.         [XmlAttribute]  
  93.         public string HospitalID;  
  94.   
  95.         [XmlAttribute]  
  96.         public string HospitalName;  
  97.   
  98.         [XmlArrayItem("Result")]  
  99.         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://write.blog.csdn.net/postedit/7210742

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值