日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

使用dynamic特性处理XML文档

發(fā)布時(shí)間:2025/6/15 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用dynamic特性处理XML文档 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

處理XML文檔是我們經(jīng)常需要進(jìn)行的一項(xiàng)工作,尤其是在進(jìn)行網(wǎng)絡(luò)服務(wù)相關(guān)編程時(shí),比如更新RSS等。在.NET 3.5中引入了Linq To XML,使得XML文檔的讀寫(xiě)已經(jīng)大大簡(jiǎn)化,而.NET 4.0中最新的dynamic特性,則將簡(jiǎn)化發(fā)揮到了極致。以處理白云黃鶴的“十大”為例,數(shù)據(jù)源地址為http://www.byhh.net/posttop10.xml,其當(dāng)前內(nèi)容為(為使結(jié)果顯示清晰,去掉了其中的鏈接地址字段):

<?xml version="1.0" encoding="gb2312" ?><?xml-stylesheet type="text/xsl" href="/style/blue/xsl/posttop.xsl"?><toppost> <post> <board>WorldSoccer</board> <title>大家支持哪隊(duì)? </title> </post> <post> <board>HUSTStudent</board> <title>地震了??? </title> </post> <post> <board>Picture</board> <title>想當(dāng)二奶的有門(mén)路了! </title> </post> <post> <board>Picture</board> <title>輕拍。。。不要太挑剔了 </title> </post> <post> <board>Humor</board> <title>【原創(chuàng)】幾個(gè)小humor </title> </post> <post> <board>HUSTStudent</board> <title>院士增選的一個(gè)疑問(wèn) </title> </post> <post> <board>WorldSoccer</board> <title>臥槽,1:55才開(kāi)始抽?? </title> </post> <post> <board>WorldSoccer</board> <title>主持MM好靚 </title> </post> <post> <board>TrainFan</board> <title>1000 </title> </post> <post> <board>Movies</board> <title>還是推薦熊貓大俠,早上才十塊錢(qián). </title> </post></toppost>

好,我們先不管它的鏈接,僅僅獲取其中的版面名(board)和標(biāo)題(title)。那么使用Linq To XML,處理方法如下:

var doc = XDocument.Load ("http://www.byhh.net/posttop10.xml");foreach (var post in doc.Element ("toppost").Elements ("post")){ Console.WriteLine ("版面:" + post.Element ("board").Value); Console.WriteLine ("標(biāo)題:" + post.Element ("title").Value.Trim ());}輸出結(jié)果:

版面:HUSTStudent
標(biāo)題:地震了???
版面:WorldSoccer
標(biāo)題:大家支持哪隊(duì)?
版面:Humor
標(biāo)題:【原創(chuàng)】幾個(gè)小humor
版面:WorldSoccer
標(biāo)題:2010年世界杯抽簽結(jié)果
版面:HUSTStudent
標(biāo)題:當(dāng)武大陷入教授門(mén)、貪污門(mén)時(shí)。華中科大又多了兩?
版面:Bicycle
標(biāo)題:雅京行紀(jì)錄片-1-雅典
版面:Picture
標(biāo)題:想當(dāng)二奶的有門(mén)路了!
版面:Picture
標(biāo)題:輕拍。。。不要太挑剔了
版面:Humor
標(biāo)題:【原創(chuàng)】關(guān)于找工作
版面:TrainFan
標(biāo)題:1000
ress any key to continue . . .

?

那在.NET 4.0 中,又是怎樣的呢,先看我最后的代碼:

XDocument doc = XDocument.Load ("http://www.byhh.net/posttop10.xml");dynamic posts = doc.Element ("toppost").AsDynamic ();foreach (var post in posts.post){ Console.WriteLine ("版面:" + post.board); Console.WriteLine ("標(biāo)題:" + post.title.Trim ());}

此時(shí),我們已經(jīng)完全去掉了啰嗦的Element和Elements方法以及Value屬性的調(diào)用,查詢(xún)post節(jié)點(diǎn)中的board節(jié)點(diǎn)、title節(jié)點(diǎn),就只需要post.board和post.title即可,多么方便!而這一切的秘密,就在于dynamic關(guān)鍵字和那個(gè)AsDynamic方法。不過(guò),不要以為你新建一個(gè)VS2010粘貼以上代碼就能運(yùn)行,“簡(jiǎn)單是以復(fù)雜為支撐的”,之所以能這么寫(xiě),是因?yàn)槲覍?shí)現(xiàn)了兩個(gè)幫助類(lèi)XmlNode和XmlNodeList(不是System.Xml命名空間中的那個(gè))來(lái)提供dynamic特性的支持,另外還實(shí)現(xiàn)了一個(gè)靜態(tài)類(lèi)來(lái)提供XElement上的擴(kuò)展方法。具體代碼如下。

class XmlNode DynamicObjectprivate XElement _element; public XmlNode (string name) : this (new XElement (name)) { } public XmlNode (XElement element) { _element = element; } public override bool TryInvokeMember (InvokeMemberBinder binder,
object[] args, out object result) { string name = binder.Name; if (String.CompareOrdinal (name, "SelectAll") == 0) { IEnumerable<XElement> selectedElements = nullif (args.Length == 0) { selectedElements = _element.Descendants (); }
else { selectedElements = _element.Descendants (args[0].ToString ()); } result = new XmlNodeList (selectedElements); return true; } else if (String.CompareOrdinal (name, "SelectChildren") == 0) { IEnumerable<XElement> selectedElements = nullif (args.Length == 0) { selectedElements = _element.Elements (); } else { selectedElements = _element.Elements (args[0].ToString ()); } result = new XmlNodeList (selectedElements); return true; } return base.TryInvokeMember (binder, args, out result); } public override bool TryGetMember (GetMemberBinder binder, out object result) { string name = binder.Name; if (String.CompareOrdinal (name, "Name") == 0) { result = _element.Name.LocalName; return true; } else if (String.CompareOrdinal (name, "Parent") == 0) { XElement parent = _element.Parent; if (parent != null) { result = new XmlNode (parent); return true; } result = nullreturn true; } else if (String.CompareOrdinal (name, "Value") == 0) { result = _element.Value; return true; } else if (String.CompareOrdinal (name, "Nodes") == 0) { result = new XmlNodeList (_element.Elements ()); return true; } else if (String.CompareOrdinal (name, "Xml") == 0) { StringWriter sw = new StringWriter (); _element.Save (sw, SaveOptions.None); result = sw.ToString (); return true; } else XAttribute attribute = _element.Attribute (name); if (attribute != null) { result = attribute.Value; return true; } var childNodes = _element.Elements (name).ToArray (); if (childNodes.Length == 1) { if (!childNodes[0].HasElements) { result = childNodes[0].Value; return true; } result = new XmlNode (childNodes[0]); return true; } else if (childNodes.Length > 1) { result = new XmlNodeList (childNodes); return true; } } return base.TryGetMember (binder, out result); } public override bool TrySetMember (SetMemberBinder binder, object value) { string name = binder.Name; if (String.CompareOrdinal (name, "Value") == 0) { _element.Value = (value != null) ? value.ToString () : String.Empty; } return base.TrySetMember (binder, value); }}

下面是XmlNodeList,用于處理子節(jié)點(diǎn)列:

class XmlNodeList DynamicObjectIEnumerableprivate List<XElement> _elements; internal XmlNodeList (IEnumerable<XElement> elements) { _elements = new List<XElement> (elements); } public override bool TryConvert (ConvertBinder binder, out object result) { Type targetType = binder.ReturnType; if (targetType == typeof (IEnumerable)) { result = thisreturn true; } return base.TryConvert (binder, out result); } public override bool TryInvokeMember (InvokeMemberBinder binder,
object[] args, out object result) { if (string.CompareOrdinal (binder.Name, "Item") == 0) { if (args.Length == 1) { XElement element = _elements[Convert.ToInt32 (args[0])]; result = new XmlNode (element); return true; } } return base.TryInvokeMember (binder, args, out result); } public override bool TryGetMember (GetMemberBinder binder, out object result) { if (string.CompareOrdinal (binder.Name, "Length") == 0) { result = _elements.Count; return true; } return base.TryGetMember (binder, out result); } #region Implementation of IEnumerable IEnumerator IEnumerable.GetEnumerator () { return new NodeEnumerator (_elements.GetEnumerator ()); }
#endregion private sealed class NodeEnumerator IEnumerator private IEnumerator<XElement> _elementEnumerator; public NodeEnumerator (IEnumerator<XElement> elementEnumerator) { _elementEnumerator = elementEnumerator; } public object Current { get XElement element = _elementEnumerator.Current; return new XmlNode (element); } } public bool MoveNext () { return _elementEnumerator.MoveNext (); } public void Reset () { _elementEnumerator.Reset (); } }}

?

可以看到,這兩個(gè)類(lèi)都繼承自DynamicObject,并覆寫(xiě)了基類(lèi)的一些方法,正因?yàn)槿绱?#xff0c;它們才能對(duì)dynamic上的調(diào)用做出特殊相應(yīng)。需要注意的是,雖然我這里是寫(xiě)了兩個(gè)類(lèi),但它們依然是與我的應(yīng)用無(wú)關(guān)的,也就是說(shuō),我處理任何XML文檔,都可以使用上述方法,千萬(wàn)不要以為我為了處理白云黃鶴的十大而特別寫(xiě)了這兩個(gè)類(lèi)。這兩個(gè)類(lèi)的代碼參考了nikhilk的博客(http://www.nikhilk.net/CSharp-Dynamic-Programming-REST-Services.aspx)的內(nèi)容,不過(guò)他的實(shí)現(xiàn)是基于.NET 4.0 CTP的,在beta2上已經(jīng)無(wú)法使用。

最后貼上那個(gè)擴(kuò)展方法AsDynamic()的實(shí)現(xiàn):

static class XmlExtensionpublic static XmlNode AsDynamic (this XElement source) { return new XmlNode (source); } public static XmlNodeList AsDynamic (this IEnumerable<XElement> source) { return new XmlNodeList (source); }}

轉(zhuǎn)載于:https://www.cnblogs.com/wwwzzg168/p/3568977.html

總結(jié)

以上是生活随笔為你收集整理的使用dynamic特性处理XML文档的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。