目录

一、加载、创建、保存、遍历XML

1.加载XML

(1)从已有文件加载XML

(2)从字符串加载XML

2.创建并保存XML

3.遍历XML

4.示例源码 

5.运行 

二、修改XML的树

1.添加节点

2.删除

3.更新

4.示例源码

5.运行效果

三、修改XML属性

1.添加

2.检索

3.删除

4.示例源码

5.运行效果


        LINQtoXML编程包含:加载xml、创建全新xml、遍历xml和修改 xml树 的信息。

一、加载、创建、保存、遍历XML

1.加载XML

(1)从已有文件加载XML

        使用LINQtoXML 加载 xml 可以从多种数据源获得,例如字符串、 XmlReader TextReader 或文件。
        从已有文件中加载xml 是最常见的xml文件操作。

(2)从字符串加载XML

        也可以使用 Parse()  方法从一个字符串加载 xml。

2.创建并保存XML

        调用XElement 对象的构造函数可以创建 xml 文档。
        使用 LINQtoXML 也可以 创建 xml 文档。

3.遍历XML

        使用 LINQtoXML xml 树中遍历 xml 是相当简单的。只需要使用 XElement XAttribute 类中的方法。Elements 和 Element 方法提供了定位到某个或某些元素的方式。 

4.示例源码 

         .NET 7.控制台应用,需要NuGet相关的程序包,其安装方法详见作者此前发布的文章。

// LINQ to XML 编程:加载 xml、创建全新 xml、保存xml
using System.IO;
using System.Xml.Linq;

namespace _10_3
{
    class Program
    {
        static void Main(string[] args)
        {
            //加载已有XML
            LoadFromFile();
            Console.WriteLine("------------------------------------------------------------");
            LoadFromString();
            Console.WriteLine("------------------------------------------------------------");
            //创建全新XML
            CreateXml();
            Console.WriteLine("------------------------------------------------------------");
            //遍历XML
            EnumXml();
            Console.WriteLine("------------------------------------------------------------");
        }
        #region 从文件加载
        /// <summary>
        /// Load()方法从文件加载XML
        /// path文件路径
        /// </summary>
        static void LoadFromFile()
        {
            string path = Directory.GetCurrentDirectory() + @"\LoadFromFile.xml";
            XElement root = XElement.Load(path);
            Console.WriteLine(root.ToString());
        }
        #endregion 从文件加载
        
        #region 从string()加载并存储
        /// <summary>
        /// Parse()方法从描述XML文件的一系列字符串加载
        /// Save()存储XML文件
        /// </summary>
        static void LoadFromString()
        {
            string path = Directory.GetCurrentDirectory() + @"\LoadFromStr.xml";
            XElement root = XElement.Parse(@"
                <db_CSharp>
                    <tb_Employee>
                        <ID>YGBH0001</ID>
                        <Name>小王</Name>
                        <db_CSharp>
                            <tb_Salary>
                                <Salary>1500</Salary>
                            </tb_Salary>
                        </db_CSharp>
                    </tb_Employee>
                        <tb_Employee>
                            <ID>YGBH0002</ID>
                            <Name>小李</Name>
                            <db_CSharp>               
                                <tb_Salary>
                                    <Salary>3000</Salary>
                                </tb_Salary>               
                            </db_CSharp>
                        </tb_Employee>
                    <tb_Employee>
                        <ID>YGBH0003</ID>
                        <Name>小刘留</Name>
                        <db_CSharp>                
                            <tb_Salary>
                                <Salary>5000</Salary>
                            </tb_Salary>
                        </db_CSharp>
                    </tb_Employee>
                </db_CSharp>
            ");
            Console.WriteLine(root.ToString());
            root.Save(path);
        }
        #endregion 从string()加载并存储

        #region 创建并存储XML
        /// <summary>
        /// XElement()方法创建记录和元素
        /// </summary>
        static void CreateXml()
        {
            string path = Directory.GetCurrentDirectory() + @"\CreateXml.xml";
            XElement root = new("Categories",
                 new XElement("Category",
                    new XElement("CategoryID", Guid.NewGuid()),
                    new XElement("CategoryName", "食品"),
                    new XElement("Description", "可以吃的东西")
                 )
             );
            Console.WriteLine(root.ToString());
            root.Save(path);
        }
        #endregion 创建并存储XML

        #region 遍历XML
        /// <summary>
        /// 如何遍历 xml 树,并获取指定元素
        /// 遍历永远离不开foreach()的
        /// </summary>
        static void EnumXml()
        {
            string path = Directory.GetCurrentDirectory() + @"\EnumXml.xml";
            string strCon = "Data Source=DESKTOP-3LV13FS;Integrated Security=True;Database=db_CSharp;";
            DataClasses1DataContext? _Linq;
            _Linq = new DataClasses1DataContext(strCon);

            XElement root = new("tb_Employee");
            root.Add(_Linq.tb_Employee.Select(c => new XElement("ID",
                new XElement("Name", c.Name)))
            );
            foreach (XElement? item in root.Elements("ID"))
            {
                if (item != null)
                {
                    Console.WriteLine(item.Element("Name")!.Value); //“!”解除CS8602,关闭编译器空检查
                }
            }
            root.Save(path);
        }
        #endregion 遍历XML
    }
}

5.运行 

<db_CSharp>
  <tb_Employee>
    <ID>YGBH0001</ID>
    <Name>小王</Name>
    <db_CSharp>
      <tb_Salary>
        <Salary>1500</Salary>
      </tb_Salary>
      <tb_Salary>
        <Salary>3000</Salary>
      </tb_Salary>
      <tb_Salary>
        <Salary>5000</Salary>
      </tb_Salary>
    </db_CSharp>
  </tb_Employee>
  <tb_Employee>
    <ID>YGBH0002</ID>
    <Name>小李</Name>
    <db_CSharp>
      <tb_Salary>
        <Salary>1500</Salary>
      </tb_Salary>
      <tb_Salary>
        <Salary>3000</Salary>
      </tb_Salary>
      <tb_Salary>
        <Salary>5000</Salary>
      </tb_Salary>
    </db_CSharp>
  </tb_Employee>
  <tb_Employee>
    <ID>YGBH0003</ID>
    <Name>小刘留</Name>
    <db_CSharp>
      <tb_Salary>
        <Salary>1500</Salary>
      </tb_Salary>
      <tb_Salary>
        <Salary>3000</Salary>
      </tb_Salary>
      <tb_Salary>
        <Salary>5000</Salary>
      </tb_Salary>
    </db_CSharp>
  </tb_Employee>
</db_CSharp>
------------------------------------------------------------
<db_CSharp>
  <tb_Employee>
    <ID>YGBH0001</ID>
    <Name>小王</Name>
    <db_CSharp>
      <tb_Salary>
        <Salary>1500</Salary>
      </tb_Salary>
    </db_CSharp>
  </tb_Employee>
  <tb_Employee>
    <ID>YGBH0002</ID>
    <Name>小李</Name>
    <db_CSharp>
      <tb_Salary>
        <Salary>3000</Salary>
      </tb_Salary>
    </db_CSharp>
  </tb_Employee>
  <tb_Employee>
    <ID>YGBH0003</ID>
    <Name>小刘留</Name>
    <db_CSharp>
      <tb_Salary>
        <Salary>5000</Salary>
      </tb_Salary>
    </db_CSharp>
  </tb_Employee>
</db_CSharp>
------------------------------------------------------------
<Categories>
  <Category>
    <CategoryID>71b53e44-9e1b-43ce-b848-501b66e6493f</CategoryID>
    <CategoryName>食品</CategoryName>
    <Description>可以吃的东西</Description>
  </Category>
</Categories>
------------------------------------------------------------
小王
小李
小刘留
小科
小亮
章子怡
汪峰
------------------------------------------------------------

二、修改XML的树

        LINQtoXML 一个重要的特性是能够方便地修改 xml 树,如 添加、删除、更新 xml 文档的内容。

1.添加节点

        使用 XNode 类的插入方法可以方便地向 xml 树添加内容。

2.删除

        使用 Remove(XElement)方法来删除元素 ,使用  RemoveAll 方法来删除 xml

3.更新

        在 LINQtoXML 中更新xml内容可以使用以下几种方法:                

4.示例源码

        .NET 7.0控制台应用程序。

// LINQtoXML 修改xml树:添加、删除、更新xml文档的内容。
using System.IO;
using System.Xml.Linq;

namespace _10_4
{
    class Program
    {
        #region 在此节点之后添加
        /// <summary>
        /// 在此节点之后添加
        /// </summary>
        static void AddAfterSelf()
        {
            string path = Directory.GetCurrentDirectory() + @"\AddAfterSelf.xml";
            XElement? root = XElement.Parse(@"
                 <Categories>
                     <Category>
                         <CategoryID>1</CategoryID>
                         <CategoryName>Beverages</CategoryName>
                         <Description>Soft drinks, coffees, teas, beers, and ales</Description>
                     </Category>
                 </Categories>
                 ");
            XElement xele = root.Element("Category")!.Element("CategoryName")!;  //!编译器禁止做null判断
            xele.AddAfterSelf(new XElement("AddDate", DateTime.Now));
            Console.WriteLine(root.ToString());
            root.Save(path);           
        }
        #endregion 在此节点之后添加

        #region 在 LINQtoXML中更新xml
        /// <summary>
        /// 更新xml
        /// 使用了ReplaceWith与SetElementValue方法更新xml
        /// </summary>
        static void Update()
        {
            string path = Directory.GetCurrentDirectory() + @"\Update.xml";
            XElement? root = XElement.Parse(@"
                 <Categories>
                     <Category>
                         <CategoryID>1</CategoryID>
                         <CategoryName>Beverages</CategoryName>
                         <Description>Soft drinks, coffees, teas, beers, and ales</Description>
                     </Category>
                 </Categories>
                 ");
            root.Element("Category")!.Element("CategoryID")!.ReplaceWith(new XElement("ID", "2"));   //修改<CategoryID>1</CategoryID>→<ID>1<ID>
            root.Element("Category")!.SetElementValue("CategoryName", "test data");                         //修改Beverages→test data
            Console.WriteLine(root.ToString());
            root.Save(path);
        }
        #endregion 在 LINQtoXML中更新xml

        #region 删除 xml
        /// <summary>
        /// 
        /// </summary>
        static void RemoveAll()
        {
            string path = Directory.GetCurrentDirectory() + @"\RemoveAll.xml";
            XElement root = XElement.Parse(@"
                 <Categories>
                     <Category>
                         <CategoryID>1</CategoryID>
                         <CategoryName>Beverages</CategoryName>
                         <Description>Soft drinks, coffees, teas, beers, and ales</Description>
                     </Category>
                 </Categories>
                 ");
            root.RemoveAll();
            Console.WriteLine(root.ToString());
            root.Save(path);
        }
        #endregion 删除 xml

        #region 删除元素
        static void Remove()
        {
            string path = Directory.GetCurrentDirectory() + @"\Remove.xml";
            XElement root = XElement.Parse(@"
                 <Categories>
                     <Category>
                         <CategoryID>1</CategoryID>
                         <CategoryName>Beverages</CategoryName>
                         <Description>Soft drinks, coffees, teas, beers, and ales</Description>
                     </Category>
                 </Categories>
                 ");
            root.Element("Category")!.Element("Description")!.Remove(); //删除元素Description
            Console.WriteLine(root.ToString());
            root.Save(path);
        }
        #endregion 删除元素

        static void Main(string[] args)
        {
            //在此节点之后添加
            AddAfterSelf();
            Console.WriteLine("------------------------------------------------------------");
            //在 LINQtoXML中更新xml
            Update();
            Console.WriteLine("------------------------------------------------------------");
            //删除xml
            RemoveAll();
            Console.WriteLine("------------------------------------------------------------");
            //删除元素
            Remove();
            Console.WriteLine("------------------------------------------------------------");
        }
    }
}

5.运行效果

<Categories>
  <Category>
    <CategoryID>1</CategoryID>
    <CategoryName>Beverages</CategoryName>
    <AddDate>2023-11-08T22:11:10.1486749+08:00</AddDate>
    <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  </Category>
</Categories>
------------------------------------------------------------
<Categories>
  <Category>
    <ID>2</ID>
    <CategoryName>test data</CategoryName>
    <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  </Category>
</Categories>
------------------------------------------------------------
<Categories />
------------------------------------------------------------
<Categories>
  <Category>
    <CategoryID>1</CategoryID>
    <CategoryName>Beverages</CategoryName>
  </Category>
</Categories>
------------------------------------------------------------

三、修改XML属性

1.添加

        LINQtoXML添加属性与添加元素是类似的,可以使用构造函数或者 Add() 方法来添加属性。

2.检索

        检索属性可以使用 Attribute(name) 方法查找指定的元素。

3.删除

        调用 XAttribute 对象的 Remove 方法来完成删除属性的操作。

4.示例源码

// LINQtoXML添加属性、检索属性和删除属性
using System.IO;
using System.Xml.Linq;

namespace _10_5
{
    class Program
    {
        #region 添加属性
        static void AddAttribute()
        {
            string path = Directory.GetCurrentDirectory() + @"\AddAttribute.xml";
            XElement root = new("Categories",
                 new XElement("Category",
                 new XAttribute("CategoryID", "1"),
                 new XElement("CategoryName", "Beverages"),
                 new XElement("Description", "Soft drinks, coffees, teas, beers, and ales"))
                 );
            root.Element("Category")!.Add(new XAttribute("AddDate", DateTime.Now.ToShortDateString())); //添加属性
            Console.WriteLine(root);
            root.Save(path);
        }
        #endregion 添加属性

        #region 检索属性
        static void SelectAttribute()
        {
            XElement root = new("Categories",
                 new XElement("Category",
                 new XAttribute("CategoryID", "1"),
                 new XElement("CategoryName", "Beverages"),
                 new XElement("Description", "Soft drinks, coffees, teas, beers, and ales"))
                 );
            XAttribute xattr = root.Element("Category")!.Attribute("CategoryID")!;  //检索指定元素
            Console.WriteLine(xattr.Name);
            Console.WriteLine(xattr.Value);
        }
        #endregion 检索属性

        #region 删除属性
        static void Remove()
        {
            string path = Directory.GetCurrentDirectory() + @"\RemoveAttri.xml";
            XElement root = new("Categories",
                  new XElement("Category",
                  new XAttribute("CategoryID", "1"),
                  new XElement("CategoryName", "Beverages"),
                  new XElement("Description", "Soft drinks, coffees, teas, beers, and ales"))
                  );
            root.Element("Category")!.Attribute("CategoryID")!.Remove(); //删除属性CategoryID
            Console.WriteLine(root.ToString());
            root.Save(path);
        }
        #endregion 删除属性

        static void Main(string[] args)
        {
            //添加属性
            AddAttribute();
            Console.WriteLine("------------------------------------------------------------");
            //检索属性
            SelectAttribute();
            Console.WriteLine("------------------------------------------------------------");
            //删除属性
            Remove();
            Console.WriteLine("------------------------------------------------------------");
        }
    }
}

5.运行效果

<Categories>
  <Category CategoryID="1" AddDate="2023-11-08">
    <CategoryName>Beverages</CategoryName>
    <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  </Category>
</Categories>
------------------------------------------------------------
CategoryID
1
------------------------------------------------------------
<Categories>
  <Category>
    <CategoryName>Beverages</CategoryName>
    <Description>Soft drinks, coffees, teas, beers, and ales</Description>
  </Category>
</Categories>
------------------------------------------------------------
11-09 21:58