幾個(gè)月來(lái),疑被SOA,一直在和xml操作打交道,SQL差不多又忘光了。現(xiàn)在已經(jīng)知道,至少有四種常用人XML數(shù)據(jù)操作方式(好像java差不多),不過(guò)還沒(méi)有實(shí)際比較過(guò)這些方式各有哪些特點(diǎn)或優(yōu)劣。正好看到網(wǎng)上也沒(méi)有這方面的實(shí)驗(yàn),偶來(lái)總結(jié)一下。
測(cè)試開(kāi)始先讀取XML源,用一個(gè)比較大的rss文件鏈接,復(fù)制到項(xiàng)目bin/debug目錄下。
Stream xmlStream = new MemoryStream(File.ReadAllBytes(path));
一、XmlDocument 方式

代碼 1 static IList testXmlDocument()
2 {
3 var doc = new XmlDocument();
4 doc.Load(xmlStream);
5 var nodeList = doc.DocumentElement.ChildNodes;
6 var lstChannel = new List<Object>(nodeList.Count );
7 foreach (XmlNode node in nodeList)
8 {
9 var channel = new
10 {
11 Title = node.SelectSingleNode("title").InnerText,
12 Link = node.SelectSingleNode("link").InnerText,
13 Description = node.SelectSingleNode("description").InnerText,
14 Content = node.SelectSingleNode("content").InnerText,
15 PubDate = node.SelectSingleNode("pubDate").InnerText,
16 Author = node.SelectSingleNode("author").InnerText,
17 Category = node.SelectSingleNode("category").InnerText
18 };
19 lstChannel.Add(channel);
20 }
21 return lstChannel;
22 }
二、XPathNavigator 方式

代碼 1 static IList testXmlNavigator()
2 {
3 var doc = new XmlDocument();
4 doc.Load(xmlStream);
5 var nav = doc.CreateNavigator();
6 nav.MoveToRoot();
7 var nodeList = nav.Select("/channel/item");
8 var lstChannel = new List<Object>(nodeList.Count);
9 foreach (XPathNavigator node in nodeList)
10 {
11 var channel = new
12 {
13 Title = node.SelectSingleNode("title").Value,
14 Link = node.SelectSingleNode("link").Value,
15 Description = node.SelectSingleNode("description").Value,
16 Content = node.SelectSingleNode("content").Value,
17 PubDate = node.SelectSingleNode("pubDate").Value,
18 Author = node.SelectSingleNode("author").Value,
19 Category = node.SelectSingleNode("category").Value
20 };
21 lstChannel.Add(channel);
22 }
23 return lstChannel;
24 }
三、XmlTextReader 方式

代碼 1 static List<Channel> testXmlReader()
2 {
3 var lstChannel = new List<Channel>();
4 var reader = XmlReader.Create(xmlStream);
5 while (reader.Read())
6 {
7 if (reader.Name == "item" && reader.NodeType == XmlNodeType.Element)
8 {
9 var channel = new Channel();
10 lstChannel.Add(channel);
11 while (reader.Read())
12 {
13 if (reader.Name == "item") break;
14 if (reader.NodeType != XmlNodeType.Element) continue;
15 switch (reader.Name)
16 {
17 case "title":
18 channel.Title = reader.ReadString();
19 break;
20 case "link":
21 channel.Link = reader.ReadString();
22 break;
23 case "description":
24 channel.Description = reader.ReadString();
25 break;
26 case "content":
27 channel.Content = reader.ReadString();
28 break;
29 case "pubDate":
30 channel.PubDate = reader.ReadString();
31 break;
32 case "author":
33 channel.Author = reader.ReadString();
34 break;
35 case "category":
36 channel.Category = reader.ReadString();
37 break;
38 default:
39 break;
40 }
41 }
42 }
43 }
44 return lstChannel;
45 }
四、Linq to XML 方式

代碼 1 static IList testXmlLinq()
2 {
3 var xd = XDocument.Load(xmlStream);
4 var list = from node in xd.Elements("channel").Descendants("item")
5 select new
6 {
7 Title = node.Element("title").Value,
8 Link = node.Element("link").Value,
9 Description = node.Element("description").Value,
10 Content = node.Element("content").Value,
11 PubDate = node.Element("pubDate").Value,
12 Author = node.Element("author").Value,
13 Category = node.Element("category").Value
14 };
15 return list.ToList();
16 }
測(cè)試結(jié)果:
| XmlDocment | 47ms |
| XPathNavigator | 42ms |
| XmlTextReader | 23ms |
| Xml Linq | 28ms |
小結(jié)一下自己的認(rèn)識(shí),XmlDocument的操作基本按W3C的DOM操作方式,不過(guò)要將全部節(jié)點(diǎn)解析成對(duì)象加載到內(nèi)存中,往往造成很大浪費(fèi)。所以微軟自己的編程規(guī)范也不推薦用它。這里由于讀取了所有節(jié)點(diǎn),可能因此性能和Navigator方式相差不大。在三種隨機(jī)讀取方式中,Xml Linq性能最高,只是方法名有點(diǎn)別扭。XmlTextReader方式是所謂的SAX,只讀向前,無(wú)疑性能最高,不過(guò)實(shí)現(xiàn)上麻煩了不少,要比較精確的控制訪問(wèn)邏輯,也無(wú)法用匿名類存儲(chǔ)數(shù)據(jù)。
.Net 3.5發(fā)布Xml Linq可以很好地取代前兩種方式,通常情況下,最好用它。只有個(gè)別場(chǎng)合,如果對(duì)性能要求極高,或者讀取Xml數(shù)據(jù)量太大不能一下子下載或讀取到內(nèi)存中,那就只好痛苦委身于XmlTextReader了。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注