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 ...
随机推荐
- 记一次服务器Tomcat优化经历
公司需要一台测试服务器来做测试用,所以花了几天时间把服务全部部署好,在部署好war包之后,发现Tomcat访问超级慢. 1.进入Tomcat的bin目录下,运行 ./catalina.sh run命令 ...
- Android 音乐播放
android简单音乐播放控制代码 这个几个月业余时间一直在做一个android项目,里面涉及到了音乐播放功能.很简单那种,播放.暂停.上一曲.下一曲.音量调节等. 音乐播放主要使用的对象是Media ...
- 马踏棋盘算法递归+回溯法实现 C语言
r为矩阵的行,c为矩阵的列 将结果输出到当前目录下的results.txt. 结果将给出:1.是否存在路径使马可以按要求走遍所有的方格: 2.解的总数: 3.程序执行的时间: #include< ...
- 发布.NET MVC网站 到Azure
最近的项目部署在Microsoft Azure,学习了一些新东西,记录下. 1.账号. 用于登录portal(https://portal.azure.cn/),账号下有对应的Subscription ...
- openCV使用
三方框架----> oprnCV使用的步骤 第一步:从官网下载framework添加到工程 1.打开 http://opencv.org/ 2. 3. 4. 3执行完之后 新打开的网页会倒计时为 ...
- Linux用户管理-中
添加用户组命令groupadd 提示:groupadd命令的使用非常简单,但在生产环境中使用的不多,因此,会简单应用即可. 与groupadd命令有关的文件有:/etc/group :用户组相关文件/ ...
- tomcat7以上,ajax post参数后台获取不到的问题
AJAX post传参后台获取不到查询参数. 网上找了各种方法,包括设置content-type,又是把json转成json格式字符串,问题依然存在,但是把post改成get又可以获取到,百思不得其解 ...
- Python序列类型
Python序列类型 序列:字符.列表.元组 所有序列都支持迭代 序列表示索引为非负整数的有序对象集合 字符和元组属于不可变序列,列表可变 1)字符 字符串字面量:把文本放入单引号.双引号或三引号中: ...
- webpack以及loader 加载命令
module.exports={ entry:'./main/main.js', output:{ path:'./build', filename:'bundle.js' }, module:{ l ...
- [图形学] Chp8.7.2 梁友栋-Barsky线段裁剪算法
这节简单介绍了梁友栋-Barsky裁剪算法的原理,只有结论并没有过程,看过http://blog.csdn.net/daisy__ben/article/details/51941608这篇文章后,大 ...