现在的位置: 首页 > 综合 > 正文

LINQ学习笔记(11) LINQ to XML—不必使用.NET专门的XML类就可读取XML文件

2012年04月04日 ⁄ 综合 ⁄ 共 8821字 ⁄ 字号 评论关闭

  今天是LINQ学习笔记中的最后一篇文章了,这一篇要介绍的内容是LINQ to XML技术,同时这也是一项比较实用的LINQ查询就用,下面就来详细介绍它。在介绍LINQ to XML之前,我们先来回顾一下传统的XML文件处理的方式,即两个基于流的类和XmlDocument类,学习完这些后我们再来真正地学习LINQ to XML的XDocument类。

一、基于流的XML处理

  读写XML文件最常用的方法是使用两个基于流的类:XmlTextWriter和XmlTextReader。它们适合处理数据量小的XML文件,这是需要注意的。

  1,写XML文件---XmlTextWriter类

  代码如下:

 1 public partial class WriteXMLByXmlTextWriter : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 //创建XmlTextWriter对象,并在构造函数中传入文件的物理路径。
6 string xmlFile = Server.MapPath(@"../Temp/DvdList.xml");

7
8 //todo:使用System.IO创建空的xml文件。
9 if (!File.Exists(xmlFile))

10 {
11 FileStream fs = null;
12 try
13 {
14 fs = File.Create(xmlFile);
15 }
16 catch (Exception ex)
17 {
18 throw new Exception(ex.Message);
19 }
20 finally
21 {
22 fs.Close();
23 }
24 }
25
26 XmlTextWriter writer = new XmlTextWriter(xmlFile, null);
27
28 //设定xml数据的缩排格式。
29 writer.Formatting = Formatting.Indented;

30 writer.Indentation = 3;
31
32 //添加xml版本声明。
33 writer.WriteStartDocument();

34
35 //添加注释。
36 writer.WriteComment("Create by Mcgrady @" + DateTime.Now.ToString());

37
38 //开始添加真正的内容,包括元素,特性等。
39 //创建父元素。
40 writer.WriteStartElement("DvdList");

41
42 //创建子节点。
43 writer.WriteStartElement("DVD");

44
45 //添加两个属性。
46 writer.WriteAttributeString("ID", "1");

47 writer.WriteAttributeString("Category", "Science Fiction");
48
49 //添加子元素。
50 writer.WriteElementString("Title", "The Matrix");

51 writer.WriteElementString("Director", "Larry Wachowski");
52 writer.WriteElementString("Price", "18.74");
53
54 //添加一个节点和其两个子元素。
55 writer.WriteStartElement("Starring");

56 writer.WriteElementString("Star", "Keanu Reeves");
57 writer.WriteElementString("Star", "Laurence Fishburne");
58
59 //为元素写入结束标签。
60 //close the <Starring> element.
61 writer.WriteEndElement();

62
63 //close the <DVD> element.
64 writer.WriteEndElement();

65
66 //写入另外一个<DVD>元素。
67 writer.WriteStartElement("DVD");

68 writer.WriteAttributeString("ID", "2");
69 writer.WriteAttributeString("category", "Drama");
70
71 writer.WriteElementString("Title", "Forrest Gump");
72 writer.WriteElementString("Director", "Robert Zemeckis");
73 writer.WriteElementString("Price", "23.99");
74
75 writer.WriteStartElement("Starring");
76 writer.WriteElementString("Star", "Tom Anks");
77 writer.WriteElementString("Star", "Robin Wright");
78
79 //close the <Starring> element and <DVD> element.
80 writer.WriteEndElement();

81 writer.WriteEndElement();
82
83 //close the <DvdList> element和关闭XmlTextWriter。
84 writer.WriteEndElement();

85 Response.Write("<script>alert('创建成功!')</script>");
86 writer.Close(); //一定要记得关闭XmlTextWriter,因为它在文件上有一个锁。
87 }

88 }

  程序创建的XML文件如下图:

  2,读XML文件---XmlTextReader类

  代码如下:

 1 public partial class ReadXmlByXmlTextReader : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 ReadXML();//调用方法
6 }

7
8 private void ReadXML()
9 {
10 string xmlFile = Server.MapPath(@"../Temp/DvdList.xml");
11
12 XmlTextReader reader = new XmlTextReader(xmlFile);//创建XmlTextReader对象
13 StringBuilder str = new StringBuilder();

14
15 while (reader.Read())//循环遍历所有节点,Read()方法类似于DataReader类的读取策略
16 {

17 //处理XML声明,注释,元素和节点的文本内容
18 switch (reader.NodeType)

19 {
20 case XmlNodeType.XmlDeclaration://XML声明
21 str.Append("Xml Declaration:");

22 str.Append(reader.Name);
23 str.Append(" ");
24 str.Append(reader.Value);
25 str.Append("<br/>");
26 break;
27 case XmlNodeType.Comment://注释
28 str.Append("Xml Comment:");

29 str.Append(reader.Value);
30 str.Append("<br/>");
31 break;
32 case XmlNodeType.Element://元素
33 str.Append("Element:");

34 str.Append(reader.Name);
35 str.Append("<br/>");
36 break;
37 case XmlNodeType.Text://节点的文本内容
38 str.Append(" -Value:");

39 str.Append(reader.Value);
40 str.Append("<br/>");
41 break;
42 }
43
44 //检查当前节点是否具有属性
45 if (reader.AttributeCount > 0)//有属性
46 {

47 while (reader.MoveToNextAttribute())//MoveToNextAttribute()方法类似于DataReader类的读取策略
48 {

49 str.Append(" -Attribute:");
50 str.Append(reader.Name);
51 str.Append("Value:");
52 str.Append(reader.Value);
53 str.Append("<br/>");
54 }
55 }
56 }
57
58 //处理完毕,关闭XmlTextReader并输出结果
59 reader.Close();

60 lbMsg.Text = str.ToString();
61 }
62 }

  当知道要取得的结构时,XmlTextReader为更快更方更地读取XML内容提供了辅助方法。例如使用MoveToContent()方法可以跳过不相关的节点(比如注释,空格以及XML声明)并在下一个元素的声明处停止。使用ReadStartElement()方法读取一个节点并同时执行基本的验证。示例如下:

 1  public partial class ReadXmlByXmlTextReader1 : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 ReadXML();
6 }
7
8 private void ReadXML()
9 {
10 string xmlFile = Server.MapPath(@"../Temp/DvdList.xml");
11
12 XmlTextReader reader = new XmlTextReader(xmlFile);//创建XmlTextReader对象
13 StringBuilder str = new StringBuilder();

14
15 reader.ReadStartElement("DvdList");
16
17 //读取所有<DVD>元素
18 while (reader.Read())

19 {
20 if ((reader.Name == "DVD") && (reader.NodeType == XmlNodeType.Element))//为元素并且元素名称为"DVD"
21 {

22 reader.ReadStartElement("DVD");
23
24 str.Append("<ul><b>");
25 str.Append(reader.ReadElementString("Title"));//调用ReadElementString()方法读取只包含文本数据的元素
26 str.Append("</b><li>");

27 str.Append(reader.ReadElementString("Director"));
28 str.Append("</li><li>");
29 str.Append(string.Format("{0:C}",Decimal.Parse(reader.ReadElementString("Price"))));
30 str.Append("</li></ul>");
31 }
32 }
33
34 //关闭XmlTextReader并输出内容
35 reader.Close();

36 lbMsg.Text = str.ToString();
37 }
38 }

程序输出结果如图:

二、内存中的XML处理:

  1、使用XmlDocument类创建XML文件:

    示例如下:

 1 public partial class WriteXmlByXmlDocument : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 WriteXML();
6 }
7
8 private void WriteXML()
9 {
10 //使用System.IO创建空的xml文件。
11 string xmlFile = Server.MapPath(@"/Temp/DvdList.xml");

12
13 if (!File.Exists(xmlFile))
14 {
15 FileStream fs = null;
16 try
17 {
18 fs = File.Create(xmlFile);
19 }
20 catch (Exception ex)
21 {
22 throw new Exception(ex.Message);
23 }
24 finally
25 {
26 fs.Close();
27 }
28 }
29
30 //创建XmlDocument对象
31 XmlDocument xmlDoc = new XmlDocument();

32
33 //创建声明
34 XmlDeclaration dec = xmlDoc.CreateXmlDeclaration("1.0", "GB2312", null);

35 xmlDoc.AppendChild(dec);
36
37 XmlComment comment = xmlDoc.CreateComment("-Create by Mcgrady@2012/01/07");
38 xmlDoc.AppendChild(comment);
39
40 //创建根节点
41 XmlElement root = xmlDoc.CreateElement("DvdList");// XmlElement表示一个元素
42 xmlDoc.AppendChild(root);

43
44 //创建第1个子节点
45 XmlNode dvd = xmlDoc.CreateElement("DVD");//XmlNode表示文档中的单个节点
46
47 //创建子节点的元素
48 XmlElement title = xmlDoc.CreateElement("Title");

49 title.InnerText = "The Matrix"; //调用InnerText属性设置元素的值
50 dvd.AppendChild(title);

51
52 XmlElement director = xmlDoc.CreateElement("Director");
53 director.InnerText = "Larry Wachowski";
54 dvd.AppendChild(director);
55
56 XmlElement price = xmlDoc.CreateElement("Price");
57 price.InnerText = "18.74";
58 dvd.AppendChild(price);
59
60 //创建第1个子节点的子节点
61 XmlNode starring = xmlDoc.CreateElement("Starring");

62
63 XmlElement star = xmlDoc.CreateElement("Star");
64 star.InnerText = "Keanu Reeves";
65 starring.AppendChild(price);
66
67 XmlElement star1 = xmlDoc.CreateElement("Star");
68 star1.InnerText = "Laurence Fishburne";
69 starring.AppendChild(star1);
70
71 //将子节点的子节点附加到子节点上
72 dvd.AppendChild(starring);

73
74 //todo:如何添加另外一个子节点呢???
75
76 //将子节点附加到根节点上
77 root.AppendChild(dvd);

78
79 //调用XmlDocument的Save()方法将数据保存到文件中
80 xmlDoc.Save(xmlFile);

81
82 //显示提示信息
83 Response.Write("<script>alert('创建成功!')</script>");

84 }
85 }

  以上代码只能创建一个子节点,如何创建第2个<DVD>子节点的方法目前还不会,也请知道的朋友可以教我一下,谢谢!

  

  2,XmlDocument类读取XML文件:

    示例如下:

 1 public partial class ReadXmlByXmlDocument : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 ReadXML();//调用方法
6 }

7
8 private void ReadXML()
9 {
10 string xmlFile = Server.MapPath(@"Temp/DvdList.xml");
11
12 //加载Xml文件到XmlDocument中
13 XmlDocument doc = new XmlDocument();

14 doc.Load(xmlFile);
15
16 //输出信息
17 lbMsg.Text = GetChildNodeDescr(doc.ChildNodes, 0);//ChildNodes属性获取节点的所有子节点,返回一个XmlNodeList
18 }

19
20 private string GetChildNodeDescr(XmlNodeList nodeList, Int32 level)//level表示嵌套层次的整数
21 {

22 //设置格式,每缩进一个层次创建一个包含3个空格的字符串,之后把字符串作为前缀加入到最终的HTML文本中
23 string indent = "";

24 for (int i = 0; i < level; i++)
25 {
26 indent += "&nbsp;&nbsp;&nbsp;";
27 }
28
29 StringBuilder str = new StringBuilder();
30
31 foreach (XmlNode node in nodeList)
32 {
33 //检查声明,注释,元素和节点的文本内容
34 switch (node.NodeType)

35 {
36 case XmlNodeType.XmlDeclaration://声明
37 str.Append("XML Declaration:");

38 str.Append(node.Name);
39 str.Append(" ");
40 str.Append(node.Value);
41 str.Append("<br/>");
42 break;
43 case XmlNodeType.Comment://注释
44 str.Append(indent);//缩进
45 str.Append("Comment:");

46 str.Append(node.Value);
47 str.Append("<br/>");
48 break;
49 case XmlNodeType.Element://元素
50 str.Append(indent);

51 str.Append("Element:");
52 str.Append(node.Name);
53 str.Append("<br/>");
54 break;
55 case XmlNodeType.Text://节点的文本内容
56 str.Append(indent);

57 str.Append(" -Value:");
58 str.Append(node.Value);
59 str.Append("<br/>");
60 break;
61 }
62
63 //检查当前节点是否有属性
64 if (node.Attributes != null)//有属性
65 {

66 foreach (XmlAttribute attrib in node.Attributes)//Attributes表示属性的集合
67 {

68 str.Append(indent);
69 str.Append(" -Attribute:");
70 str.Append(attrib.Name);
71 str.Append("Value:");
72 str.Append(attrib.Value);
73 str.Append("<br/>");
74 }
75 }
76
77 //如果节点有子节点,代码递归调用GetChildNodeDescr()方法,向它传送当前节点的ChildNodes集合以及当前缩进层次加1的值。
78 if (node.HasChildNodes)

79 {
80 str.Append(GetChildNodeDescr(node.ChildNodes,level+1));
81 }
82 }
83 return str.ToString();
84 }
85 }

  前面讲了传统的XML文件操作类XmlTextWriter,XmlTextReader和XmlDocument类,下面来总结一下真正与LINQ相关的XML文件操作类XDocument。

 

XDocument类,千呼万唤始出来:

  1、XDocument类创建XML文件:

 1 public partial class WriteXMLbyXDocument : System.Web.UI.Page
2 {
3 protected void Page_Load(object sender, EventArgs e)
4 {
5 string xmlFile = Server.MapPath(@"Temp/DvdList.xml");//调用Server.MapPath方法获取文件物理路径
6
7 //todo:建立xml文件
8 if (!File.Exis

抱歉!评论已关闭.