用C#实现仿Ruby的XML Builder
Ruby中有個(gè)很好用的XML API,在頁(yè)面實(shí)現(xiàn)XML輸出很方便。比如有個(gè)聯(lián)系人Contacts的XML輸出,Ruby里面是這樣寫(xiě)的。
... xml.contacts doxml.contact(:type => "work") doxml.name("Joe Smith")end end ...
借用.Net 4.0的dynamic特性,用C#實(shí)現(xiàn)一個(gè)XmlBuilder。測(cè)試代碼如下:
?
XmlBuilderTest [TestFixture]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.愛(ài)好("看電影"),
xmlBuilder.Address("type", "home",
xmlBuilder.Street("123 Main St."),
xmlBuilder.City("SpringField"))));
Console.WriteLine("XML: \n" + result.ToString());
}
}
為實(shí)現(xiàn)上述功能,我們創(chuàng)建類(lèi)XmlBuilder,繼承DynamicObject,并override其TryInvokeMember方法。
?
XmlBuilder public class XmlBuilder : DynamicObject{
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;
//分析參數(shù)類(lèi)型,區(qū)分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總數(shù)為奇數(shù),定義最末一個(gè)字符串為InnerText。
if (strings.Count % 2 == 1)
{
text = strings.Last();
strings.RemoveAt(strings.Count - 1);
}
//將strings成對(duì)封裝為XAttribute。
for (var i = 0; i < strings.Count; i=i+2)
{
attributes.Add(new XAttribute(strings[i], strings[i+1]));
}
//返回動(dòng)態(tài)類(lèi)型。
return new { Documents = documents, Attributes = attributes, Text = text };
}
/// <summary>
/// 類(lèi)型判斷
/// </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;
}
}
運(yùn)行XmlBuilderTest,得到的結(jié)果如下:
?
?
XML:<Contacts>
<Contact type="team-member" id="1">
<Name>Joe Smith</Name>
<Phone type="work">(123) 456-7890</Phone>
<愛(ài)好>看電影</愛(ài)好>
<Address type="home">
<Street>123 Main St.</Street>
<City>SpringField</City>
</Address>
</Contact>
</Contacts>
?
?
-- 聲明 --
1、沒(méi)太動(dòng)腦筋,主要的實(shí)現(xiàn)思路(包括部分代碼),來(lái)源于In a Perfect World。(帶梯子可訪問(wèn))原作者給的代碼有問(wèn)題,我在上面做了修改。
2、運(yùn)行dynamic,需要在.Net 4.0環(huán)境下,引用程序集Microsoft.CSharp.dll。
-- 下載 --
所有代碼在這兒下載。XmlBuilderTest.zip
轉(zhuǎn)載于:https://www.cnblogs.com/workingbird/articles/CSharp_dynamic_xmlbuilder_like_ruby.html
總結(jié)
以上是生活随笔為你收集整理的用C#实现仿Ruby的XML Builder的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在Linux下安装配置Oracle11g
- 下一篇: C#将照片或图片转化为byte[]存入数