Use DynamicXElement to create xml

  XML作为一种通用数据格式,.net进行了专门的封装。从开始的XMLDoc到现在的 Linq to XML一直不断的简化XML的操作。

  .net4.0的出现给偶们带来了dynamic特性,ExpandoObject和DynamicObject这2个类很拉风~~~

  比如我们要生成一段简历的XML:

 


  
<? xml version="1.0" encoding="utf-8" ?>
< Resume >
< Name > Prime </ Name >
< Date > 2011/6/2 </ Date >
< City > Nanjing </ City >
< Contact >
< QQ > 277389861 </ QQ >
< MSN > prime.li@live.cn </ MSN >
</ Contact >
< A >
< B >
< C >
< D >
< E >
< City > Nanjing </ City >
</ E >
</ D >
</ C >
</ B >
</ A >
</ Resume >

  让我们看看用Linq to XML是如何创建Resume.xml的:


  
public void Resume()
{
XDocument doc
= new XDocument();
var resume
= new XElement( " Resume " );
resume.Add(
new XElement( " Name " , " Prime " ));
resume.Add(
new XElement( " Date " , DateTime.Today.ToShortDateString()));
resume.Add(
new XElement( " City " , " Nanjing " ));
resume.Add(
new XElement( " Contact " ));
resume.Element(
" Contact " ).Add( new XElement( " QQ " , " 277389861 " ));
resume.Element(
" Contact " ).Add( new XElement( " MSN " , " prime.li@live.cn " ));
resume.Add(
new XElement( " A " , new XElement( " B " , new XElement( " C " , new XElement( " D " , new XElement( " E " , resume.Element( " City " )))))));
doc.Add(resume);
doc.Save(
" Resume.xml " );
}

  是不是比较麻烦呢?如果用我的DynamicXElement类可以这样写:


  
public void DynamicResume()
{
dynamic resume
= new DynamicXElement( " Resume " );
resume.Name
= " Prime " ;
resume.Date
= DateTime.Today.ToShortDateString();
resume.City
= " Nanjing " ;
resume.Contact.QQ
= " 277389861 " ;
resume.Contact.MSN
= " prime.li@live.cn " ;
resume.A.B.C.D.E
= resume.City;
resume.Save(
" DynamicResume.xml " );
}

  是不是感觉很干净呢?而且读起来很清晰明了,有层次感!O(∩_∩)O

  其实实现起来很简单,利用DyanmicObject,我们包装一个XElement就可以搞定,如下:


  
public class DynamicXElement : DynamicObject
{
public DynamicXElement( string name)
:
this ( new XElement(name))
{ }

public DynamicXElement(XElement element)
:
this (element, true )
{ }

public DynamicXElement( string name, bool dyanmicCreateElement)
:
this ( new XElement(name), dyanmicCreateElement)
{ }

public DynamicXElement(XElement element, bool dyanmicCreateElement)
{
Element
= element;
DynamicCreateElement
= dyanmicCreateElement;
}

public XElement Element
{
get ; private set ; }

/// <summary>
/// 是否支持动态创建节点
/// 比如你写resume.A.B.C.D.E,其实A,B,C,D都是空的
/// true则会自动创建A,B,C,D,E这些节点,否则false则必须先创建好A,B,C,D这4个节点
/// </summary>
public bool DynamicCreateElement
{
get ; private set ; }

public static DynamicXElement Load( string uri)
{
var element
= XElement.Load(uri);
return new DynamicXElement(element);
}

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var element
= Element.Element(binder.Name);
if (element != null )
{
result
= new DynamicXElement(element);
return true ;
}
else
{
if (DynamicCreateElement)
{
var child
= new XElement(binder.Name);
Element.Add(child);
result
= new DynamicXElement(child);
return true ;
}
else
{
result
= null ;
return false ;
}
}
}

public override bool TrySetMember(SetMemberBinder binder, object value)
{
var element
= Element.Element(binder.Name);
if (element != null )
{
element.SetValue(value);
}
else
{
if (value is DynamicXElement)
{
var child
= new XElement(binder.Name);
var innerElement
= ((DynamicXElement)value).Element;
child.Add(innerElement);
Element.Add(child);
}
else
{
Element.Add(
new XElement(binder.Name, value));
}
}
return true ;
}

public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type.Equals( typeof (XElement)))
{
result
= Element;
return true ;
}
return base .TryConvert(binder, out result);
}

public override bool TryInvokeMember(InvokeMemberBinder binder, object [] args, out object result)
{
try
{
var flags
= BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance;
result
= typeof (XElement).InvokeMember(binder.Name, flags, null , Element, args);
return true ;
}
catch
{
result
= null ;
return false ;
}
}
}


如果还想有其他功能,你可以自己扩展~~~

原理太简单了,就是拦截所有的方法和属性,然后自定义如何Handle。这样其实我们可以在运行时就可以增加属性和方法等。

参考资料:.Net 4.0 DynamicObject使用(下)

转载于:https://www.cnblogs.com/prime/archive/2011/06/02/DynamicXElement.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值