使用属性可以控制对象的 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) 文档文件。没有将属性应用于字段时,架构会以下列方式描述元素。


         


        <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. 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。

        <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. 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. }