用C#实现仿Ruby的XML Builder
Ruby中有个很好用的XML API,在页面实现XML输出很方便。比如有个联系人Contacts的XML输出,Ruby里面是这样写的。
...
xml.contacts doxml.contact(:type => "work") doxml.name("Joe Smith")end
end
...
借用.Net 4.0的dynamic特性,用C#实现一个XmlBuilder。测试代码如下:
public class XmlBuilderTest
{
[Test]
public void CreatorTest()
{
dynamic xmlBuilder = new XmlBuilder();
var result = xmlBuilder.Contacts(
xmlBuilder.Contact("type", "team-member", "id", "1",
xmlBuilder.Name("Joe Smith"),
xmlBuilder.Phone("type", "work", "(123) 456-7890"),
xmlBuilder.爱好("看电影"),
xmlBuilder.Address("type", "home",
xmlBuilder.Street("123 Main St."),
xmlBuilder.City("SpringField"))));
Console.WriteLine("XML: \n" + result.ToString());
}
}
为实现上述功能,我们创建类XmlBuilder,继承DynamicObject,并override其TryInvokeMember方法。
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
var arguments = ParseArguments(args);
var rootElement = new XElement(binder.Name, arguments.Text, arguments.Attributes);
foreach (XDocument xDocument in arguments.Documents)
rootElement.Add(xDocument.FirstNode);
result = new XDocument(rootElement);
return true;
}
private static dynamic ParseArguments(object[] arguments)
{
var documents = new List<XDocument>();
var strings = new List<string>();
var attributes = new List<XAttribute>();
string text = null;
//分析参数类型,区分string和XDocument
foreach (var arg in arguments)
{
XDocument xDocArgument;
string stringArgument;
if (CastAs(arg, out xDocArgument))
documents.Add(xDocArgument);
else if (CastAs(arg, out stringArgument))
strings.Add(stringArgument);
}
//如果strings总数为奇数,定义最末一个字符串为InnerText。
if (strings.Count % 2 == 1)
{
text = strings.Last();
strings.RemoveAt(strings.Count - 1);
}
//将strings成对封装为XAttribute。
for (var i = 0; i < strings.Count; i=i+2)
{
attributes.Add(new XAttribute(strings[i], strings[i+1]));
}
//返回动态类型。
return new { Documents = documents, Attributes = attributes, Text = text };
}
/// <summary>
/// 类型判断
/// </summary>
private static bool CastAs<T>(object value, out T castedValue)
{
if (value is T)
{
castedValue = (T)value;
return true;
}
castedValue = default(T);
return false;
}
}
运行XmlBuilderTest,得到的结果如下:
<Contacts>
<Contact type="team-member" id="1">
<Name>Joe Smith</Name>
<Phone type="work">(123) 456-7890</Phone>
<爱好>看电影</爱好>
<Address type="home">
<Street>123 Main St.</Street>
<City>SpringField</City>
</Address>
</Contact>
</Contacts>
-- 声明 --
1、没太动脑筋,主要的实现思路(包括部分代码),来源于In a Perfect World。(带梯子可访问)原作者给的代码有问题,我在上面做了修改。
2、运行dynamic,需要在.Net 4.0环境下,引用程序集Microsoft.CSharp.dll。
-- 下载 --
所有代码在这儿下载。XmlBuilderTest.zip
转载于:https://www.cnblogs.com/workingbird/articles/CSharp_dynamic_xmlbuilder_like_ruby.html
用C#实现仿Ruby的XML Builder相关推荐
- 常用ruby gem
常见gems: Devise 用于快速构建用户功能,如:注册,登陆,个人设置,找回密码 oauth OmniAuth 如果你需要在项目中实现三方平台(如: Twitter, Facebook, 新浪微 ...
- Ruby on Rails 之旅(七)—— Ruby on Rails 入门(5)
为什么80%的码农都做不了架构师?>>> 接下来我们一起学习一下respond_to 字面意思是响应给...我们可以理解为,你要什么格式. 以往一样的操作返回不同的格式,我们大 ...
- xml 和android脚本之家,Android利用Document实现xml读取和写入操作
本文实例为大家分享了利用Document实现xml读取和写入操作,供大家参考,具体内容如下 首先先来介绍一下什么xml?xml是可扩展标记语言,他可以用来标记数据,定义数据类型.是一种允许用户对自己标 ...
- Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应
在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...
- Spring Boot中如何扩展XML请求和响应的支持
在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...
- Spring Boot中扩展XML请求和响应的支持
在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...
- ruby 读取文本_使用Ruby进行文本处理
ruby 读取文本 在与Perl或Python相同的页面上,Ruby具有强大的功能,可以成为强大的文本处理语言. 本文简要地讨论了Ruby的文本数据处理能力,以及如何使用它来有效处理文本数据的不同格式 ...
- 3分钟教你实现仿微信底部导航栏效果(BottomNavigationView + ViewPager)
文章目录 实现效果图 前言 XML布局 menu文件 ViewPager的使用 PagerAdapter(Java) Activity中实现 上下联动 侧滑带动按钮选择 点击底部按钮带动页面 自定义选 ...
- Rails5 Controller Document
更新: 2017/06/28 大致完成全部 更新: 2017/06/29 补充module文件命名规则 更新: 2017/07/09 补充session的设置 更新: 2018/03/06 修正ren ...
最新文章
- java.io几种读写文件的方式
- ASP.NET Core 上传多文件 超简单教程
- 【渝粤题库】国家开放大学2021春2509学前教育学题目
- 【转来警醒自己】最近的一些面试感悟
- 微软免费软件项目DreamSpark更名为Microsoft Imagine
- 一文领略 HTTP 的前世今生
- linux 中的MYSQL命令汇总
- 转载------工作10年的人总结的6句话
- 7限制cpu使用_macOS限制CPU或进程使用率
- python:关于三级菜单的新手实现
- 图文并茂超详细搭建memcache缓存服务器(nginx+php+memcache+mysql)
- jetson nano opencv 打开 CSI摄像头_opencv-python图形图像处理入门基础知识
- TFT-LCD与FSMC控制器
- 综合布线:如何选择多模光纤和单模光纤
- 基于DDD的微服务设计和开发实战
- 人口红利消失,电销要怎么做才能立足市场?
- C语言七巧板游戏制作,绘本里的七巧板游戏
- soul网关mysql8_深度解析 Soul 网关——数据同步
- 解析飞凌嵌入式i.MX8MM在智慧医疗麻醉系统中的应用方案
- nodejs读取服务器json文件,nodejs读写json文件的简单方法(必看)
热门文章
- 微课视频小学用计算机画画,初识电脑绘画
- 计算机课题推荐人意见,课题推荐人意见怎么写
- 用-force –opengl 指令_OpenGL-使用Tessellation技术绘制Cubic Bézier Patches
- python numpy库等差不均分_numpy.linspace 生成等差数组的方法
- 分享3个干货满满的Python实战项目,点赞收藏
- 13个Pandas实用技巧,有点香 !
- 太难得了!大厂数据分析实战项目资料首次公开!免费,速领!
- 什么叫计算机网络阻塞,计算机网络中的“线端阻塞”释义
- php mysql查询时间_php查询时间段 mysql时间查询
- 数据分析学习01-matplotlib绘图工具基本操作