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


      今天是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.Exists(xmlFile))

    9 {
    10 FileStream fs = null;
    11 try
    12 {
    13 fs = File.Create(xmlFile);
    14 }
    15 catch (Exception ex)
    16 {
    17 throw new Exception(ex.Message);
    18 }
    19 finally
    20 {
    21 fs.Close();
    22 }
    23 }
    24
    25 //使用XDocument类创建xml文件
    26 XDocument doc = new XDocument( //params可变参数
    27 new XDeclaration("1.0","utf-8","yes"),

    28 new XComment("Create by Mcgrady @"+DateTime.Now.ToString()),
    29 new XElement("DvdList",
    30 new XElement("DVD",
    31 new XAttribute("ID","1"),
    32 new XAttribute("Category","Science Fiction"),
    33 new XElement("Title","The Matrix"),
    34 new XElement("Director","Larry Wachowski"),
    35 new XElement("Price","18.74"),
    36 new XElement("Starring",
    37 new XElement("Star","Keanu Reeves"),
    38 new XElement("Star","Laurence Fishburne")
    39 )
    40 ),
    41 new XElement("DVD",
    42 new XAttribute("ID", "2"),
    43 new XAttribute("Category", "Drama"),
    44 new XElement("Title", "Forrest Gump"),
    45 new XElement("Director", "Robert Zemeckis"),
    46 new XElement("Price", "23.99"),
    47 new XElement("Starring",
    48 new XElement("Star", "Tom Hanks"),
    49 new XElement("Star", "Robin Wright")
    50 )
    51 )
    52 )
    53 );
    54
    55 doc.Save(xmlFile);//调用Save()方法保存到文件中。
    56

    57 Response.Write("<script>alert('创建成功!')</script>");
    58 }
    59 }

      2,使用XDocument类读取XML文件:

     1 public partial class ReadXMLByXDocument : System.Web.UI.Page
    2 {
    3 protected void Page_Load(object sender, EventArgs e)
    4 {
    5 string xmlFile = Server.MapPath(@"Temp/DvdList.xml");//获取文件路径
    6

    7 XDocument doc = XDocument.Load(xmlFile);//创建XDocument对象并调用Load()方法载入xml文件
    8

    9 StringBuilder str = new StringBuilder();
    10
    11 //使用foreach语句遍历
    12 //Element()方法获取指定名称的元素
    13 //Elements()方法获取当前节点下的所有元素
    14 foreach (XElement element in doc.Element("DvdList").Elements())

    15 {
    16 str.Append("<ul><b>");
    17 str.Append((String)element.Element("Title"));
    18 str.Append("</b><li>");
    19 str.Append((String)element.Element("Director"));
    20 str.Append("</li><li>");
    21 str.Append(string.Format("{0:C}",(Decimal)element.Element("Price")));
    22 str.Append("</li></ul>");
    23 }
    24 lbMsg.Text = str.ToString();//输出结果
    25 }

    26 }

      以上总结了使用XmlTextWriter类创建xml文件&使用XmlTextReader类读取xml文件,使用XmlDocument类创建和读取xml文件,最后重点总结了使用LINQ中的XDocument类对象创建和读取Xml文件。

      这些就是这篇文章的全部内容,希望园友们提出宝贵意见,有不正确的地方也欢迎与我讨论。

  • 相关阅读:
    Pycharm 设置python文件自动生成头部信息模板
    Python3.0 调用HTMLTestRunner生成的报告中不能显示用例中print函数的输出
    Python3.0 操作MySQL数据库执行SQL语句
    js时间戳转为日期格式
    Vue脚手架(vue-cli)安装总结
    Vue的生命周期
    常用的ES6语法
    学习python登录demo
    CSS的垂直居中和水平居中总结
    CSS清除浮动方法总结
  • 原文地址:https://www.cnblogs.com/mcgrady/p/2313706.html
Copyright © 2020-2023  润新知