使用反射来编写实体类的XML
前言:
开发过程中经常需要返回某实体类的列表,公司通常用的都是XML格式的接口,小猪借鉴了公司前辈留下的代码一直是类似这么写的:
public static string GetXMLList(IList<Article> articlelist)
{
using (MemoryStream memoryStream = new MemoryStream())
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.NewLineChars = Environment.NewLine;
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{
xmlWriter.WriteStartDocument(true);
xmlWriter.WriteStartElement("Articles");
if (articlelist != null)
{
foreach (var article in articlelist)
{
xmlWriter.WriteStartElement("Article");
xmlWriter.WriteStartAttribute("id");
xmlWriter.WriteString(article.Id.ToString());
xmlWriter.WriteEndAttribute(); xmlWriter.WriteStartElement("Title");
xmlWriter.WriteCData(article.Title);
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Summary");
xmlWriter.WriteCData(article.Summary);
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Author");
xmlWriter.WriteCData(article.Author);
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("CreateDate");
xmlWriter.WriteCData(article.CreateDate.ToString("yyyy-MM-dd"));
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("BannerURL");
xmlWriter.WriteCData(article.BannerURL);
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("ImageURL");
xmlWriter.WriteCData(article.ImageURL);
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("ImageAuthor");
xmlWriter.WriteCData(article.ImageAuthor);
xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Category");
xmlWriter.WriteCData(article.Category.ToString());
xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement();
}
}
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
}
string xml = Encoding.UTF8.GetString(memoryStream.ToArray());
return xml;
}
}
生成的代码:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Articles>
<Article id="83">
<Title><![CDATA[存储]]></Title>
<Summary><![CDATA[asdsa]]></Summary>
<Author><![CDATA[asdsa]]></Author>
<CreateDate><![CDATA[2013-12-30]]></CreateDate>
<BannerURL><![CDATA[/Images/2013年12月/20131230153738573.png]]></BannerURL>
<ImageURL><![CDATA[/Images/2013年12月/20131230153731941.png]]></ImageURL>
<ImageAuthor><![CDATA[sda]]></ImageAuthor>
<Category><![CDATA[1]]></Category>
</Article>
<Article id="81">
<Title><![CDATA[存储]]></Title>
<Summary><![CDATA[asdsa]]></Summary>
<Author><![CDATA[asdsa]]></Author>
<CreateDate><![CDATA[2013-12-30]]></CreateDate>
<BannerURL><![CDATA[/Images/2013年12月/20131230153738573.png]]></BannerURL>
<ImageURL><![CDATA[/Images/2013年12月/20131230153731941.png]]></ImageURL>
<ImageAuthor><![CDATA[sda]]></ImageAuthor>
<Category><![CDATA[1]]></Category>
</Article>
</Articles>
代码一直延续到昨天!小猪决定重构他!
重构一:去除重复代码
首先上述代码最大的问题就是大量的复制粘贴,违背了DRY(Don't Repeated Yourself)原则。多个字段就要多粘贴一次,为了解决这个问题在遍历实体列表时使用下属代码:
using (MemoryStream memoryStream = new MemoryStream())
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.NewLineChars = Environment.NewLine;
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{
xmlWriter.WriteStartDocument(true);
xmlWriter.WriteStartElement("Articles");
if (articlelist != null)
{
foreach (var article in articlelist)
{
Type type = typeof(Article);
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
object ob = propertyInfo.GetValue(article, null);
if (null != ob)
{
xmlWriter.WriteStartElement(propertyInfo.Name);
xmlWriter.WriteCData(ob.ToString());
xmlWriter.WriteEndElement();
}
}
xmlWriter.WriteEndElement();
}
}
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
} string xml = Encoding.UTF8.GetString(memoryStream.ToArray());
return xml;
}
可是这样只能遍历Article类型,其他类型还是使用不了这个方法
重构二:加入泛型
在最原始的代码中每为一个实体增加类似功能的时候都要把那一整块代码复制过来然后做修改,我们在重构一中还是没有解决这个问题,为了使上面的方法能够在以后被重复利用我们加入泛型
public static string GetXMLList<T>(IList<T> articlelist)
{
using (MemoryStream memoryStream = new MemoryStream())
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.NewLineChars = Environment.NewLine;
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{
xmlWriter.WriteStartDocument(true);
xmlWriter.WriteStartElement("Roots");
Type type = typeof(T);
if (articlelist != null)
{
foreach (var article in articlelist)
{
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
object ob = propertyInfo.GetValue(article, null);
if (null != ob)
{
xmlWriter.WriteStartElement(propertyInfo.Name);
xmlWriter.WriteCData(ob.ToString());
xmlWriter.WriteEndElement();
}
}
xmlWriter.WriteEndElement();
}
}
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
} string xml = Encoding.UTF8.GetString(memoryStream.ToArray());
return xml;
}
}
这样代码完成了多类型的使用,但是却把所有的共有属性都写进了XML,在实际使用中我们可能不希望把所有属性都列进来,例如是否推荐字段,阅读权限字段等等~
重构三:
重构:...
...
重构N
为了使每个节点上面增加Id属性,定义一个抽象类Listable。抽象类中包涵自动Id,让需要提供列表的实体类继承至这个抽象类:
/*==========================================================
*作者:SmallerPig
*时间:2013/12/30 17:26:01
*版权所有:无锡睿阅数字科技有限公司
============================================================*/
namespace RY.Entity
{
public abstract class Listable
{
public int Id { get; set; }
}
}
实体类来继承它。例如:
public class Article : Listable
{
public string Title { get; set; } public string Summary { get; set; } }
然后给泛型方法加上约束,在该指定Id的地方加上id属性!
static string ToXML<T>(IList<T> TList, string ingor) where T : Listable
{
using (MemoryStream memoryStream = new MemoryStream())
{
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Indent = true;
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.NewLineChars = Environment.NewLine;
using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
{
xmlWriter.WriteStartDocument(true);
xmlWriter.WriteStartElement("Roots");
if (TList != null)
{
Type type = typeof(T);
foreach (T t in TList)
{
xmlWriter.WriteStartElement(type.Name);
xmlWriter.WriteStartAttribute("id");
xmlWriter.WriteString(t.Id.ToString());
xmlWriter.WriteEndAttribute();
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
if (propertyInfo.CanRead && propertyInfo.Name.ToLower() != ingor.ToLower())
{
if (propertyInfo.PropertyType == typeof(DateTime))
{
xmlWriter.WriteStartElement(propertyInfo.Name);
DateTime dt = Convert.ToDateTime(propertyInfo.GetValue(t, null));
xmlWriter.WriteCData(dt.ToString("yyyy-MM-dd hh:mm:ss"));
xmlWriter.WriteEndElement();
}
if (propertyInfo.PropertyType == typeof(String) || propertyInfo.PropertyType == typeof(int))
{
object ob = propertyInfo.GetValue(t, null);
if (null != ob)
{
xmlWriter.WriteStartElement(propertyInfo.Name);
xmlWriter.WriteCData(ob.ToString());
xmlWriter.WriteEndElement();
}
}
}
}
xmlWriter.WriteEndElement();
}
}
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
}
string xml = Encoding.UTF8.GetString(memoryStream.ToArray());
return xml;
}
}
最后效果:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Roots>
<Article id="83">
<Title><![CDATA[存储]]></Title>
<Summary><![CDATA[asdsa]]></Summary>
<Author><![CDATA[asdsa]]></Author>
<Category><![CDATA[1]]></Category>
<CreateDate><![CDATA[2013-12-30 03:37:52]]></CreateDate>
<BannerURL><![CDATA[/Images/2013年12月/20131230153738573.png]]></BannerURL>
<ImageURL><![CDATA[/Images/2013年12月/20131230153731941.png]]></ImageURL>
<ImageAuthor><![CDATA[sda]]></ImageAuthor>
<Id><![CDATA[83]]></Id>
</Article>
<Article id="82">
<Title><![CDATA[存储]]></Title>
<Summary><![CDATA[asdsa]]></Summary>
<Author><![CDATA[asdsa]]></Author>
<Category><![CDATA[1]]></Category>
<CreateDate><![CDATA[2013-12-30 03:37:51]]></CreateDate>
<BannerURL><![CDATA[/Images/2013年12月/20131230153738573.png]]></BannerURL>
<ImageURL><![CDATA[/Images/2013年12月/20131230153731941.png]]></ImageURL>
<ImageAuthor><![CDATA[sda]]></ImageAuthor>
<Id><![CDATA[82]]></Id>
</Article>
</Roots>
使用反射来编写实体类的XML的更多相关文章
- 简单实体类和xml文件的相互转换
最近写一个题目,要求将一组员工实体类转换成xml文件,或将xml文件转换成一组实体类.题目不难,但写完感觉可以利用泛型和反射将任意一个实体类和xml文件进行转换.于是今天下午立马动手 试了下,做了个简 ...
- 实体类转xml
看项目中需要实体类转xml,大家是拼接的.感觉可以利用反射实现.于是写了下 代码如下 package com.kevin.util; import org.springframework.util.O ...
- 利用JAXB实现java实体类和xml互相转换
1.应用场景 在使用WebService实现数据上传下载,数据查询时,可以利用JAXB实现java实体类和xml互相转换 2.Demo 2.1 student.java 实体类,包含list(set同 ...
- C#实体类生成XML与XML Schema文档
一.实体类生成XML private void CreateXML() { Type[] objType = DBEntityRegst(); foreach (var item in objType ...
- 使用C#实现实体类和XML相互转换
一.实体类转换成XML 将实体类转换成XML需要使用XmlSerializer类的Serialize方法,将实体类序列化 public static string XmlSerialize<T& ...
- Android利用反射机制为实体类属性赋值
在做android项目时,有时会遇到从网络上获取json类型数据,赋值给实体类,实体类属性少可以一个一个的赋值,如果实体类有很多属性,赋值可能就要耗很长的功夫了,幸好Java给我们提供了反射机制.下面 ...
- 实现实体类和Xml相互转化
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.X ...
- 利用Java反射机制对实体类的常用操作工具类ObjectUtil
代码: ObjectUtil类: import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.Simpl ...
- C#实体类与XML相互转换
1.实体类与XML相互转换 将实体类转换成XML需要使用XmlSerializer类的Serialize方法,将实体类序列化. 把XML转换成相应的实体类,需要使用到XmlSerializer类的De ...
随机推荐
- Chrome浏览器的密码隐患
谷歌浏览器的密码填充使得登陆账号很方便 但在你了解了Chrome的密码特性机制后,你该做点什么了 1.如何查看已保存的密码 Chrome 密码管理器的进入方式:右侧扳手图标→设置→显示高级设置→密码和 ...
- [转载] 彻底学习STL中的Allocator
原文: http://cissco.iteye.com/blog/379093 帮助我们理解allocator的原理 Allocator是C++语言标准库中最神秘的部分之一.它们很少被显式使用,标准也 ...
- JavaScript屏蔽Backspace键
原文:http://www.cnblogs.com/xdp-gacl/p/3785806.html 今天在IE浏览器下发现,当把使用readonly="readonly"属性将文本 ...
- mybatis动态sql中where标签的使用
where标记的作用类似于动态sql中的set标记,他的作用主要是用来简化sql语句中where条件判断的书写的,如下所示: <select id="selectByParams&qu ...
- IIS_Mvc发布
网站发布步骤: 这部分是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接 ...
- Kafka 消息存储及检索(作者:杜亦舒)
Kafka 消息存储及检索 原创 2016-02-29 杜亦舒 性能与架构 Kafka是一个分布式的消息队列系统,消息存储在集群服务器的硬盘Kafka中可以创建多个消息队列,称为topic,消息的生产 ...
- 针对ASP.NET页面实时进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
在介绍之前,先简单说一说ASP.NET服务端GZIP压缩模块的作用及工作原理,很多人编写网页的时候页面因为使用了大量的JS特效又或者放置很多大型动态广告导致了页面或脚本体积庞大,通常都会使用一些压缩工 ...
- neon汇编,C嵌入汇编
1. Neon-intrics.pdf中的 void vst2q_u16(__transfersize(16) uint16_t * ptr, uint16x8x2_t val);// VST2.16 ...
- 检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
/** * Author: laixiangran. * Created by laixiangran on 2015/12/02. * 检测访问网页的浏览器呈现引擎.平台.Windows操作系统.移 ...
- ubuntu server nginx 安装与配置
ubuntu server nginx 安装与配置 一:关于nginx http://wiki.ubuntu.org.cn/Nginx http://nginx.org/cn http://wiki. ...