博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#.NET解析XML(使用属性控制 XML 序列化)
阅读量:6094 次
发布时间:2019-06-20

本文共 8354 字,大约阅读时间需要 27 分钟。

hot3.png

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

我就又补习了一下。

分享一下学习成果吧。

示例代码下载:

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

 

使用属性可以控制对象的 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:  // 
1234567890
.  

若要重新命名元素,可以更改这种默认行为。下面的代码演示属性 (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;  }  

序列化实例可能如下所示。

  
      
          
Haley
      
    

通过应用 XmlArrayAttribute,可以按照以下方式更改 XML 元素的名称。

public class Group{      [XmlArray("TeamMembers")]      public Employee[] Employees;  }  

生成的 XML 可能如下所示。

  
      
          
Haley
      
  
  

另一方面,XmlArrayItemAttribute 可以控制如何序列化数组中包含的项。请注意,该属性将应用于返回数组的字段。

public class Group{      [XmlArrayItem("MemberName")]      public Employee[] Employees;  }  

生成的 XML 可能如下所示。

  
      
Haley
  
  
  

序列化派生类

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

序列化实例可能如下所示。

  
      
          
Haley
      
      
          
Ann
          
3
      
    
  

将数组作为元素序列进行序列化

通过将 XmlElementAttribute 应用于返回数组的字段,还可以将该数组作为 XML 元素的平面序列进行序列化,如下所示。

public class Group{      [XmlElement]      public Employee[] Employees;  }  

序列化实例可能如下所示。

  
      
Haley
  
  
      
Noriko
  
  
      
Marco
  
  
  

区别两种 XML 流的另一个方法是,使用 XML 架构定义工具,从编译好的代码生成 XML 架构 (XSD) 文档文件。没有将属性应用于字段时,架构会以下列方式描述元素。

   

将 XmlElementAttribute 应用于字段时,生成的架构会以下列方式描述元素。

   

序列化 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。

相比之下,如果是对该类的实例进行序列化,则只能在 XML 文档中找到 NewGroupName

<NewGroupName> . . .</NewGroupName>

最后来贴一个自己的XML解析实例

XML结构如下:

  
      
          
              
              
              
          
          
              
              
              
          
          
              
              
              
          
          
 为空(预留)
              
          
              
                    
                      
H==高,L=低,N=正常
                      
11.1
                      
                      
 
                      
 
                      
                                    
                      
H==高,L=低,N=正常
                      
11.1
                      
                      
 
                      
 
                      
                                                    
              
                  
                      
A=异常,N=正常
                      
                      
病种,未见异常
                      
检查部位:胸部
                      
影像所见
                      
检查结论                                    
                      
A=异常,N=正常
                      
                      
病种,未见异常
                      
检查部位:腹部
                      
影像所见
                      
检查结论                                                      
              
                  
                      
A=异常,N=正常
                      
1.5
                      
病种,未见异常
                      
检查部位
                      
影像所见
                      
检查结论                                    
                      
A=异常,N=正常
                      
0.8
                      
病种,未见异常
                      
检查部位
                      
影像所见
                      
检查结论                                                  
  

实例

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
();              r.Person.Results.Add("1");              r.Person.Results.Add("1");              r.Person.Results.Add("1");              r.Person.Suggestions = new List
();              r.Person.Suggestions.Add("2");              r.Person.Suggestions.Add("2");              r.Person.Suggestions.Add("2");                r.MedicalItems = new List
();              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 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
(r));                                       }      }        [Serializable]      public class Root      {          //[XmlElement]          public Person Person;            public List
 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
 Results;            [XmlArrayItem("Conclusion")]          public List
 Conclusions;            [XmlArrayItem("Suggestion")]          public List
 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;      }        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      {          /// 
          /// 反序列化XML为类实例          ///           /// 
          /// 
          /// 
          public static T DeserializeXML
(string xmlObj)          {              XmlSerializer serializer = new XmlSerializer(typeof(T));              using (StringReader reader = new StringReader(xmlObj))              {                  return (T)serializer.Deserialize(reader);              }          }            /// 
          /// 序列化类实例为XML          ///           /// 
          /// 
          /// 
          public static string SerializeXML
(T obj)          {              using (StringWriter writer = new StringWriter())              {                  new XmlSerializer(obj.GetType()).Serialize((TextWriter)writer, obj);                  return writer.ToString();              }          }      }      }  

 

转载于:https://my.oschina.net/u/3058673/blog/833349

你可能感兴趣的文章
JS隐式转换--宽松相等(==)
查看>>
Node.js 及 Vue-cli 安装
查看>>
12.设计模式
查看>>
【JS基础】从JavaScript中的for...of说起(上) - iterator 和 generator
查看>>
自定义图片裁剪之双指缩放思路
查看>>
前端的伙伴们, chrome canary 控制台添加了一个非常实用的功能
查看>>
Serverless助力AI计算:阿里云ACK Serverless/ECI发布GPU容器实例
查看>>
export 和 export default的一些区别以及引入时解构的用法
查看>>
HTTP2基础教程-读书笔记(一)发展史和诞生背景
查看>>
移动端调试方法汇总
查看>>
未来人类会成为机器人吗?
查看>>
js原生日历
查看>>
Cookie简介
查看>>
sublime text3 中 CTags: Rebuild Tags执行之乱码解决方法
查看>>
js的几种sleep函数
查看>>
跨域问题及解决方案
查看>>
每日任务1
查看>>
全局注入SplashActivity界面框架。支持首次打开App开屏界面#再进程存活的情况下从后台进入前台注入开屏界面#再进程存活的情况下锁屏再亮屏进入开屏界面...
查看>>
如何不花钱实现简单的短信验证功能
查看>>
结合element-ui 的el-upload组件支持分片上传
查看>>