DynamicXml
/*
var xml = @"<root><books>
<book is_read=""false""><author>Test</author></book>
<book is_read=""true""><author>Test2</author></book>
</books></root>";
dynamic book = new DynamicXml(xml);
Console.WriteLine(book.Book[1]);
*/
public class DynamicXml : DynamicObject, IEnumerable
{
static readonly DynamicXml Null = new DynamicXml();
#region Friendly Xml
static readonly Regex TagRegex = new Regex(@"<(/?)(.*?)>");
static readonly Regex AttrRegex = new Regex(@"(\w+)=""");
static string Friendly(string txt)
{
var dictionary = new Dictionary<string, string>();
Func<string, string> formatTag = tag =>
{
if (!dictionary.ContainsKey(tag))
dictionary.Add(tag, FormatText(tag));
return dictionary[tag];
};
var result = TagRegex.Replace(txt, delegate(Match match)
{
var original = match.Result("$2");
string worked;
#region tag work
if (original.Contains(" "))
{
var index = original.IndexOf(" ", StringComparison.Ordinal);
worked = formatTag(original.Substring(0, index)) +
AttrRegex.Replace(original.Substring(index),
attr => formatTag(attr.Result("$1")) + "=\"");
}
else
{
worked = formatTag(original);
}
#endregion
return match.Result("<$1") + worked + ">";
});
return result;
}
static string FormatText(string txt)
{
var sb = new StringBuilder();
var up = true;
foreach (var c in txt)
{
if (c == '_')
{
up = true;
}
else
{
if (up)
{
sb.Append(c.ToString(CultureInfo.InvariantCulture).ToUpper());
up = false;
}
else
{
sb.Append(c.ToString(CultureInfo.InvariantCulture).ToLower());
}
}
}
return sb.ToString();
}
#endregion
private readonly List<XElement> _elements = new List<XElement>();
DynamicXml() { }
public DynamicXml(string text, bool friendly = true)
{
try
{
var doc = XDocument.Parse(text);
if (friendly)
{
var formatted = doc.ToString();
doc = XDocument.Parse(Friendly(formatted));
}
_elements = new List<XElement> { doc.Root };
}
catch (Exception ex)
{
Console.Write(ex);
throw;
}
}
protected DynamicXml(XElement element)
{
_elements = new List<XElement> { element };
}
protected DynamicXml(IEnumerable<XElement> elements)
{
_elements = new List<XElement>(elements);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = Null;
switch (binder.Name)
{
case "Count":
result = _elements.Count;
break;
default:
{
var items = _elements.Descendants(XName.Get(binder.Name)).ToList();
if (!items.Any())
{
if (_elements.Count == 1)
{
var attr = _elements[0].Attribute(XName.Get(binder.Name));
if (null != attr)
{
result = attr.Value;
}
}
}
else
{
result = new DynamicXml(items);
}
}
break;
}
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
var index = (int)indexes[0];
result = new DynamicXml(_elements[index]);
return true;
}
public IEnumerator GetEnumerator()
{
return _elements.Select(element => new DynamicXml(element)).GetEnumerator();
}
public override string ToString()
{
if (_elements.Count == 1 && !_elements[0].HasElements)
{
return _elements[0].Value;
}
return string.Join("\n", _elements);
}
public static implicit operator string(DynamicXml dyn)
{
return Null == dyn ? null : dyn.ToString();
}
public static implicit operator DynamicXml(string xml)
{
return new DynamicXml(xml);
}
}
DynamicXml的更多相关文章
- 记录下DynamicXml和HtmlDocument 使用方式
之前解析都是XmlDocument.Load 而现在可以利用DynamicXml生成Dynamic对象实现强类型操作,很好用. /// <summary> /// 根据Xml路径动态解析成 ...
- 理解C# 4 dynamic(3) – DynamicObject的使用
上篇文章"理解C# 4 dynamic(2) – ExpandoObject的使用" 了解了ExpandoObject的基本使用. 但ExpandoObject的问题就是它是一个万 ...
- 超级懒汉编写的基于.NET的微信SDK
一.前言 特别不喜欢麻烦的一个人,最近碰到了微信开发.下载下来了一些其他人写的微信开发“框架”,但是被恶心到了,实现的太臃肿啦. 最不喜欢的就是把微信返回的xml消息在组装成实体类,所以会比较臃肿,现 ...
- [转贴]超级懒汉编写的基于.NET的微信SDK
一.前言 特别不喜欢麻烦的一个人,最近碰到了微信开发.下载下来了一些其他人写的微信开发“框架”,但是被恶心到了,实现的太臃肿啦. 最不喜欢的就是把微信返回的xml消息在组装成实体类,所以会比较臃肿,现 ...
- 十七、C# 反射、特性和动态编程
反射.特性和动态编程 1.访问元数据 2.成员调用 3.泛型上的反射 4.自定义特性 5.特性构造器 6.具名参数 7.预定义特性 8.动态编程 特性(attribute)是在一个程序集中插入 ...
- 基于.NET的微信SDK
超级懒汉编写的基于.NET的微信SDK 一.前言 特别不喜欢麻烦的一个人,最近碰到了微信开发.下载下来了一些其他人写的微信开发“框架”,但是被恶心到了,实现的太臃肿啦. 最不喜欢的就是把微信返回的 ...
- 【第二十篇】C#微信H5支付 非微信内浏览器H5支付 浏览器微信支付
微信开发者文档 微信H5支付官方文档 请阅读清楚 最起码把所有参数看一遍 这个地方也可以看看 微信案例 http://wxpay.wxutil.com/mch/pay/h5.v2.php,请在微 ...
- C# - 表达式与语句
表达式与语句(Expression&Statement) 操作数(Operands) 1.数字.2.字符.3.变量.4.类型.5.对象.6.方法 操作符(Operator) 参考:C# - 操 ...
- C#学习笔记12
1.在使用反射时,反射可以绕过安全访问级别(private.protected)修饰的类或属性,来获取需要的信息. 2.泛型的反射:可以使用Type.ContainsGenericParameters ...
随机推荐
- 很好的复习资料: SQL语句到底怎么写 ?
本文用到的数据库如下: CREATE DATABASE exam; /*创建部门表*/ CREATE TABLE dept( deptno INT PRIMARY KEY, dname VARCHAR ...
- Vue.js 基础指令实例讲解(各种数据绑定、表单渲染大总结)——新手入门、高手进阶
Vue.js 是一套构建用户界面的渐进式框架.他自身不是一个全能框架--只聚焦于视图层.因此它非常容易学习,非常容易与其它库或已有项目整合.在与相关工具和支持库一起使用时,Vue.js 也能完美地驱动 ...
- SharePoint 2016 安装配置流程及需要注意的地方
1. 安装域, 安装后创建一个用户用于之后的安装配置, 例如 SPAdmin@XXXXX.com 2. 安装sql server 2016 将要安装sql server 的服务器加入域, 并将域账 ...
- Python3 面向对象程序设计(类)
一.自定义类 1.属性与方法 格式: class classname: def __init__(self,a,b): self.a=a self.b=b def ... >一般都有一个__ ...
- tcp/ip通信传输流
利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信,发送端从应用层往下走,接收端则往应用层方向走. 我们用HTTP进行举例 客户端在应用层发出想要看到某个web页面的http请求.HT ...
- 这个类复制文本文件FileCopy
package JBJADV003; import java.io.File;import java.io.BufferedReader;import java.io.BufferedWriter;i ...
- vijos1760题解
题目: 现在有n个人,题目给出了他们每个人所在市县的编号.他们站在一个从左向右的队伍中.小L不在队列中.他想找到一个长度不超过D的区域,使他能够找到最多的不同地方的朋友.要求输出能找到的朋友所在不同市 ...
- java IO之 序列流 集合对象Properties 打印流 流对象
序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...
- MD5加盐 Java加密算法
MD5带盐值的java加密算法 import java.security.MessageDigest; public class PasswordEncoder { private final s ...
- Java+Tomcat + Idea + Jrebel 实现热部署
1. 首先安装idea的jrebel插件, jrebel是收费的,所以要在网上下载验证码. 2. 安装好以后再setting 菜单能看到一个jrebel的菜单. 3. 4.其中需要选中frame失去 ...