• 在C#中使用属性控制 XML 序列化来解析XML


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

  • 相关阅读:
    [CISCN2019 华北赛区 Day1 Web2]ikun
    [BJDCTF 2nd]简单注入
    [BJDCTF2020]ZJCTF,不过如此
    [BJDCTF2020]The mystery of ip
    [SWPU2019]Web1
    [WesternCTF2018]shrine
    [BJDCTF 2nd]假猪套天下第一
    [BJDCTF2020]Mark loves cat
    [GWCTF 2019]我有一个数据库
    C语言学习笔记_函数与函数库
  • 原文地址:https://www.cnblogs.com/gc2013/p/3668788.html
Copyright © 2020-2023  润新知