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 ...
随机推荐
- Linux下nginx+多个Tomcat负载均衡的实现
博主原创,转载请注明. 由于项目需要,共创建了10个Tomcat端,由nginx负责转发.9个Tomcat端口分别是8080,11000,12000,13000,14000,15000,16000,1 ...
- php5.6在yum下安装redis
yum install redis php-redis --enablerepo=remi,remi-php56 设置redis开机自动启动,具体路径以实际为准, echo "/usr/bi ...
- css里面position:relative与position:absolute的区别
position:absolute这个是绝对定位:是相对于浏览器的定位.比如:position:absolute:left:20px;top:80px; 这个容器始终位于距离浏览器左20px,距离浏览 ...
- Java post提交表单限制
According to Tomcat7's documentation, setting maxPostSize in Connector to a value less than or equal ...
- Maven pom.xml配置详解
POM的全称是“ProjectObjectModel(项目对象模型)”. 声明规范 <projectxmlns="http://maven.apache.org/POM/4.0.0&q ...
- 给xcode项目修改名字
在xcode项目开发中,经常会遇到需要修改项目名字的问题, 但是xcode本身修改项目名字比较麻烦,有时候修改的不完全,有时候修改了项目无法打开,无奈只能建一个新项目.这里提供一种修改xcode项目名 ...
- Go学习笔记(二)十分钟上手
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 变量&常量 变量 变量名由字母.数字.下划线组成,不能以数字开头. ... var ( A int //默 ...
- Oracle存储过程、包、方法使用总结
/** *@author:zhengwei *@date:2017-04-28 *@desc:存储过程用法总结 */ CREATE OR REPLACE PROCEDURE MYPROCEDURE(P ...
- js继承之Object.create()
通过 Object.create() 方法,使用一个指定的原型对象和一个额外的属性对象创建一个新对象.这是一个用于对象创建.继承和重用的强大的新接口.说直白点,就是一个新的对象可以继承一个对象的属性, ...
- 【故障处理】ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
今天在使用冷备份文件重做从库时遇到一个报错,值得研究一下. 版本:MySQL5.6.27 一.报错现象 dba:(none)> start slave; ERROR (HY000): Slave ...