wcf 基础教程 契约 Contract 控制xml输出 数据契约DataContract序列化前身 XmlSerializer xml序列化
在上一篇博客介绍了xml序列化的原则,wcf 基础教程 契约 Contract 数据契约DataContract序列化前身 XmlSerializer xml序列化, 今天我们沿着上次描述的继续前进,这次的内容可能会很少,但是应该说如果我们想更进一步的控制xml,那么还是很有必要的。好了,不多说了,xml序列化使用的是.Net 中的XmlSerializer,在System.Xml.Serialization.XmlSerializer 命名空间下。上次仅仅是XmlSerializer 采用的默认的序列化规则。很多情况下,我们需要控制xml的输出,那么就需要我们人为的干预和控制。
在xml序列化过程中,如果我们定义了一个A,A继承自B,但是如果我们是通过B的序列化不能应用于A。这是什么意思呢?也就是说如果我们序列化的时候是B作为类型,那么我们在反序列化的时候也必须反序列化为B,而不能是A。这个有点复杂,需要我们慢慢体会。我也理解的不是特别透彻。
在上一篇博客中,我们生成的xml中 XmlElement只是单纯的属性名称,如果我们想为属性名称添加命名空间应该怎么做呢?有码有真相
其实最主要的是XmlAttributeOverrides 和XmlAttributes 来实现控制xml的输出,现在就来实现我们的需求。
但是我们采用声明的方式来解决这个问题,
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 using System.Diagnostics; 8 9 namespace Chinaer.WcfDemo.ConsoleClient 10 { 11 class Program 12 { 13 static void Main(string[] args) 14 { 15 //Person person = new Person(25, Guid.NewGuid()) 16 //{ 17 // Date = DateTime.Now 18 //}; 19 //person.UserName = "guozhiqi"; 20 ////person.UserPwd = "123"; 21 //Serialize<Person>(person, "person.xml"); 22 Person person = new Person() 23 { 24 Age = 12, 25 UserPwd = "21", 26 UserName = "郭志奇", 27 Date = DateTime.Now 28 }; 29 30 using (XmlWriter writer = new XmlTextWriter("person.xml", Encoding.UTF8)) 31 { 32 XmlSerializer serializer = new XmlSerializer(typeof(Person)); 33 serializer.Serialize(writer, person); 34 } 35 36 Process.Start("person.xml"); 37 Console.Read(); 38 } 39 40 /// <summary> 41 /// 序列化方法 42 /// </summary> 43 /// <typeparam name="T"></typeparam> 44 /// <param name="instace"></param> 45 /// <param name="fileName"></param> 46 public static void Serialize<T>(T instace, string fileName) 47 { 48 using (XmlWriter writer = new XmlTextWriter(fileName, Encoding.UTF8)) 49 { 50 XmlSerializer serializer = new XmlSerializer(typeof(T)); 51 serializer.Serialize(writer, instace); 52 } 53 Process.Start(fileName); 54 } 55 } 56 [XmlRoot(ElementName="guozhiqi",Namespace="http://www.guozhiqi.com")] 57 /// <summary> 58 /// 定义一个实体类 Person 59 /// </summary> 60 public class Person 61 { 62 private Guid _id; 63 64 private DateTime _date; 65 //注意我们没有默认的构造函数 66 internal double Age { get; set; } //私有字段 年龄 67 /// <summary> 68 /// 通过XmlAttributeAttribute 序列化成xml属性 69 /// </summary> 70 [XmlAttribute(AttributeName="GuidID",Namespace="http://guidID")] 71 public Guid ID 72 { 73 get { return _id; } 74 set 75 { 76 _id = value; 77 } 78 } //公有的随机数 79 [XmlElement(ElementName="DateTime",Namespace="http://date")] 80 public DateTime Date 81 { 82 set 83 { 84 _date = value; 85 } 86 get 87 { 88 return _date; 89 } 90 } 91 92 public string UserName { get; set; } 93 94 public string UserPwd { get; set; } 95 public Person() { } 96 public Person(double age, Guid id) 97 { 98 this.Age = age; 99 100 } 101 } 102 103 }
请注意上面的代码,我们先贴出来生成的xml,对比着看比较容易。
1 <?xml version="1.0" encoding="utf-8"?>
<guozhiqi xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
d1p1:GuidID="00000000-0000-0000-0000-000000000000"
xmlns:d1p1="http://guidID" xmlns="http://www.guozhiqi.com">
<DateTime xmlns="http://date">2013-03-21T23:31:13.8584896+08:00</DateTime>
<UserName>郭志奇</UserName><UserPwd>21</UserPwd></guozhiqi>
我们看到在字段或属性上应用XmlAttributeAttribute 特性将其序列化为Xml属性,同时可以指定名称(别名)或命名空间。
通过在字段或属性上应用XmlElementAttribute特性将其序列化为Xml元素,可以指定Name、NameSpace和Order 排序。至于xml属性和元素有什么区别,大家可以搜索一下。其中区别很小。
控制xml结构的输出通过声明方式很简单,但是通过编程方式也不是特别难,因为今天连着写了两篇博客,确实没精神了,写了将近两个小时。直呼 程序员 伤不起啊