文档章节

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

rabbit_mom
 rabbit_mom
发布于 2017/02/07 15:14
字数 2162
阅读 57
收藏 0

今天需要解析一个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://write.blog.csdn.net/postedit/7210742

本文转载自:http://blog.csdn.net/bdstjk/article/details/7210742

rabbit_mom
粉丝 3
博文 25
码字总数 12119
作品 0
程序员
私信 提问
.NET对象的XML序列化和反序列化

序列化的概念 序列化是指一个对象的实例可以被保存,保存成一个二进制串,当然,一旦被保存成二进制串,那么也可以保存成文本串了。 比如,一个计数器,数值为2,我们可以用字符串“2”表示。...

王二狗子11
2017/12/26
0
0
.NET高级代码审计(第六课) DataContractSerializer反序列化漏洞

原文来自安全客,作者:Ivan1ee@360云影实验室 原文链接:https://www.anquanke.com/post/id/175796 相关阅读: 《.NET 高级代码审计(第一课)XmlSerializer 反序列化漏洞》 《.NET 高级代码...

安全客
04/04
0
0
XmlSerializer 对象的Xml序列化和反序列化

这篇随笔对应的.Net命名空间是System.Xml.Serialization;文中的示例代码需要引用这个命名空间。 为什么要做序列化和反序列化? .Net程序执行时,对象都驻留在内存中;内存中的对象如果需要传...

长平狐
2012/06/08
227
0
XML解析方法详解

今日目标:DOM、 SAX、 STAX、 XML解析API 今日重点:JAXP DOM解析 、JAXP SAX解析、XML PULL解析。 XML现在已成为一种通用的数据交换格式,平台的无关性使得很多场合都需要用到XML。深入了...

honzhang
2017/12/26
0
0
XSLT语法 在.net中使用XSLT转换xml文档示例

XSL即可扩展的样式表文件。 可以格式化xml的显示,也可以将xml转换成需要的另一种格式。 学习XSL必须熟悉XPath。XSL和XPath一样简单强大,容易学习。 1. XSL既然可以格式化xml的显示样式,我...

长平狐
2012/06/08
91
0

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
6
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部