零、文章目录

XML详解

1、XML是什么

XML(Extensible Markup Language)是一种用于存储和传输数据的标记语言。它由万维网联盟(W3C)开发。XML被广泛用于数据交换、数据存储、Web服务、网络协议(如SOAP)等方面。它是一种非常流行的数据格式,在Web开发中扮演着重要角色。XML与HTML类似,但XML更加灵活和可扩展,它允许开发人员创建自己的标记,而不是只限于HTML中预定义的标记。XML的主要特点包括:

可扩展性:XML允许开发人员创建自定义的标记和元素,以表示数据和结构,这使得XML可以用于多种应用程序和领域。结构化:XML文档由嵌套的元素和属性组成,这使得XML可以表示复杂的数据结构。标准化:XML支持标准化的字符编码,如UTF-8和UTF-16,这使得XML可以在不同的平台和应用程序之间进行交换和处理。简单易读:XML文档具有清晰的层次结构和良好的可读性,这使得XML易于编写和理解。

2、XML文档基本结构

(1)XML声明

每个XML文档都必须包含一个声明,它描述了XML文档的版本和编码方式。例如,在以下的XML文档中,声明了XML版本1.0,编码方式为UTF-8

(2)根元素

XML文档必须有一个根元素,它包含了所有其他元素。根元素通常是所有其他元素的父元素。例如,在以下的XML文档中,<根元素>是根元素

<根元素>

(3)元素

元素是XML文档的基本单位,它包含文本或其他元素。元素通过标签来标识,例如,以下的XML文档中,

是段落元素的开始和结束标签

这是一个段落。

(4)属性

属性是元素的附加信息,它们提供了关于元素的额外信息。属性在开始标签中定义,并以名称/值对的形式出现。例如,以下的XML文档中,href是链接元素的属性,值为一个URL:

这是一个链接

(5)注释

注释用于在XML文档中添加注释和说明。注释以结束。例如,以下的XML文档中,是一个注释:

(6)处理指令

处理指令提供了关于XML处理器如何处理文档的指令。例如,以下的XML文档中,是一个处理指令,它指定了一个与XML文档关联的样式表:

(7)命名空间

命名空间:一个用于定义XML文档中元素和属性的范围和作用域的机制。它允许在XML文档中定义多个不同的命名空间,以便将元素和属性限制在特定的范围内。 在XML中,命名空间被定义为一个URI(统一资源标识符),它为XML元素提供一个唯一的名称。命名空间可以用于区分具有相同名称的元素或属性,使用命名空间可以帮助避免名称冲突。 在XML文档中,命名空间可以用以下两种方式定义:

在元素上定义命名空间:可以在XML文档的根元素或特定元素上使用命名空间属性来定义命名空间。例如:

使用XML命名空间前缀:可以使用XML命名空间前缀来定义命名空间,并指定其URI。例如:

Value

多个命名空间示例如下

xmlns:ns2="http://www.example.com/namespace2">

Value 1

Value 2

3、C#对xml文件结构的抽象

XML 文档被抽象为一个 XmlDocument 对象,该对象包含了整个 XML 文档的内容。XmlDocument 对象可以通过 XmlReader 或 XmlWriter 类来读取或写入 XML 文件。XML 文档中的元素被抽象为 XmlElement 对象,这些对象包含了元素的名称、属性和子元素。开发人员可以通过 XmlElement 对象的属性来访问元素的名称、属性和子元素。XML 文档中的属性被抽象为 XmlAttribute 对象,这些对象包含了属性的名称和值。开发人员可以通过 XmlAttribute 对象的属性来访问属性的名称和值。XML 文档中的文本内容被抽象为 XmlText 对象,这些对象包含了文本内容。开发人员可以通过 XmlText 对象的属性来访问文本内容。一些其他的类和接口,如 XmlNodeList、XmlNodeReader、XmlNodeWriter 等,用于处理 XML 文档中的节点列表、读取和写入 XML 节点等。这些类都在命名空间System.Xml下面。

4、C#对xml文档的增删改查

(1)创建一个XML文件

//创建xml文档

XmlDocument xmldoc = new XmlDocument();

//加入XML声明

XmlDeclaration xmldecl = xmldoc.CreateXmlDeclaration("1.0", "UTF-8", null);

xmldoc.AppendChild(xmldecl);

// 创建一个注释节点

XmlNode comment = xmldoc.CreateComment("这是一个注释");

xmldoc.AppendChild(comment);

//加入一个根元素

XmlElement employees = xmldoc.CreateElement("Employees");

xmldoc.AppendChild(employees);

//根元素加入一些子元素

for (int i = 1; i < 5; i++)

{

// 创建一个注释节点

XmlNode comment1 = xmldoc.CreateComment("Employee" + i);

employees.AppendChild(comment1);

XmlElement employee = xmldoc.CreateElement("Employee"+i);//创建一个子节点

employee.SetAttribute("name", "人员" + i);//设置该节点属性

XmlElement age = xmldoc.CreateElement("Age");//创建一个孙节点

age.InnerText = (18+i).ToString();//设置文本

employee.AppendChild(age);//添加到子节点中

XmlElement sex = xmldoc.CreateElement("Sex");//创建一个孙节点

sex.InnerText = i % 2 == 0 ? "男" : "女";//设置文本

employee.AppendChild(sex);//添加到子节点中

XmlElement salary = xmldoc.CreateElement("Salary");

salary.InnerText = (10000 + i * 100).ToString();

employee.AppendChild(salary);

employees.AppendChild(employee);//将子节点添加到根节点中

}

//保存创建好的XML文档

xmldoc.Save("test.xml");

生成的文件内容如下

19

10100

20

10200

21

10300

22

10400

(2)读取XML文件内容

//创建xml文档

XmlDocument xmldoc = new XmlDocument();

//导入指定xml文件

XmlReaderSettings settings = new XmlReaderSettings();

settings.IgnoreComments = true;//忽略文档里面的注释,注释也是节点,但是无法转换成XmlElement,所以这里不忽略,下面转换就报错

//XmlReader是用liu需要using包起来,读完释放资源,防止占用

using (XmlReader reader = XmlReader.Create("test.xml", settings))

{

xmldoc.Load(reader);

}

//获取根节点

XmlElement employees=xmldoc.DocumentElement;

//遍历根节点的子节点

foreach (XmlElement employee in employees.ChildNodes)

{

StringBuilder sb = new StringBuilder();

sb.Append($"{employee.Name}--{employee.GetAttribute("name")}");

foreach (XmlElement child in employee.ChildNodes)

{

sb.Append($"--{child.Name}:{child.InnerText}");

}

Console.WriteLine(sb.ToString());

}

读取内容如下

Employee1--人员1--Age:19--Sex:女--Salary:10100

Employee2--人员2--Age:20--Sex:男--Salary:10200

Employee3--人员3--Age:21--Sex:女--Salary:10300

Employee4--人员4--Age:22--Sex:男--Salary:10400

(3)修改XML文件内容

//创建xml文档

XmlDocument xmldoc = new XmlDocument();

//导入指定xml文件

xmldoc.Load("test.xml");

//获取根节点

XmlElement employees = xmldoc.DocumentElement;

//添加节点

XmlElement newemployee = xmldoc.CreateElement("Employee4");//创建一个子节点

newemployee.SetAttribute("name", "新的人员4");//设置该节点属性

XmlElement age = xmldoc.CreateElement("Age");//创建一个孙节点

age.InnerText = "88";//设置文本

newemployee.AppendChild(age);//添加到子节点中

XmlElement sex = xmldoc.CreateElement("Sex");//创建一个孙节点

sex.InnerText ="女博士";//设置文本

newemployee.AppendChild(sex);//添加到子节点中

XmlElement salary = xmldoc.CreateElement("Salary");

salary.InnerText = "20000";

newemployee.AppendChild(salary);

employees.InsertAfter(newemployee, employees.ChildNodes[1]);//将子节点添加到第1个节点后

//删除节点

XmlNode nodeDelete=employees.SelectSingleNode("//Employee1");//筛选匹配的第一个节点

employees.RemoveChild(nodeDelete);//删除筛选出来的节点

//修改节点

XmlElement nodeUpdate = employees.SelectSingleNode("//Employee2") as XmlElement;//筛选匹配的第一个节点

nodeUpdate.SetAttribute("name", "新的人员2");

nodeUpdate["Age"].InnerText = "99";

nodeUpdate["Sex"].InnerText = "男博士";

nodeUpdate["Salary"].InnerText = "18888";

//筛选多个节点

XmlNodeList nodes= employees.SelectNodes("//Employee4");

Console.WriteLine("打印筛选出的节点信息");

foreach (XmlElement employee in nodes)

{

StringBuilder sb = new StringBuilder();

sb.Append($"{employee.Name}--{employee.GetAttribute("name")}");

foreach (XmlElement child in employee.ChildNodes)

{

sb.Append($"--{child.Name}:{child.InnerText}");

}

Console.WriteLine(sb.ToString());

}

//保存创建好的XML文档

xmldoc.Save("test.xml");

Console.WriteLine();

Console.WriteLine("打印修改后的结果");

Console.WriteLine(File.ReadAllText("test.xml"));

运行效果

打印筛选出的节点信息

Employee4--新的人员4--Age:88--Sex:女博士--Salary:20000

Employee4--人员4--Age:22--Sex:男--Salary:10400

打印修改后的结果

88

女博士

20000

99

男博士

18888

21

10300

22

10400

(4)多命名空间XML操作

//创建xml文档

XmlDocument xmldoc = new XmlDocument();

//加入一个根元素

XmlElement root = xmldoc.CreateElement("root");

//根元素添加命名空间属性

root.SetAttribute("xmlns:ns1", "http://www.example.com/namespace1");

root.SetAttribute("xmlns:ns2", "http://www.example.com/namespace2");

//添加子节点

XmlElement element1 = xmldoc.CreateElement("ns1:element1");

element1.InnerText = "Value 1";

root.AppendChild(element1);

//添加子节点

XmlElement element2 = xmldoc.CreateElement("ns2:element2");

element2.InnerText = "Value 2";

root.AppendChild(element2);

//添加子节点

XmlElement element3 = xmldoc.CreateElement("element3");

element3.SetAttribute("xmlns", "http://example.com/child");

element3.InnerText = "Value 3";

root.AppendChild(element3);

xmldoc.AppendChild(root);

//保存创建好的XML文档

xmldoc.Save("namespace.xml");

Console.WriteLine();

Console.WriteLine("多个命名空间");

Console.WriteLine();

Console.WriteLine(File.ReadAllText("namespace.xml"));

运行结果

多个命名空间

Value 1

Value 2

Value 3

(5)XPath筛选节点数据

在C#中,可以使用XPath来筛选XML节点数据。XPath是一种用于在XML文档中查找信息的语言,它可以用来在XML文档中对元素和属性进行遍历。 XPath常见节点选择方法

//:选择所有的节点,包括根节点。.:选择当前节点。..:选择当前节点的父节点。/:选择根节点下的所有节点。//A:选择所有名为"A"的节点。//A/B:选择所有名为"A"的节点的"B"子节点。//A/*:选择所有名为"A"的节点下的所有任意节点//A[1]:选择文档中第一个名为"A"的节点。//A[@属性='属性值']:选择所有名为"A"的节点,且属性=属性值的节点。//A[contains(@属性, “属性值”)]:选择所有名为"A"的节点,且属性包含属性值的节点。//A[B='C']:选择所有名为"A"的且子节点B等于’C’的节点。//A[B!='C']:选择所有名为"A"的且子节点B不等于’C’的节点。//A[B!='C']:选择所有名为"A"的且子节点B不等于’C’的节点。//A[B>'C']:选择所有名为"A"的且子节点B大于’C’的节点。//A[B<'C']:选择所有名为"A"的且子节点B小于’C’的节点。//A[B>='C']:选择所有名为"A"的且子节点B大于等于’C’的节点。//A[B<='C']:选择所有名为"A"的且子节点B小于等于’C’的节点。//A[B<='C' and B>='D']:选择所有名为"A"的且子节点B小于等于’C’且B大于等于’D’的节点。//A[B<='C' or B>='D']:选择所有名为"A"的且子节点B小于等于’C’或者B大于等于’D’的节点。//*[@属性='属性值']:选择所有属性=属性值的节点。//A[@属性='属性值'][1]:选择文档中第一个名为"A"的节点,且属性=属性值的节点。//A[@属性='属性值']/B:选择所有名为"A"的节点,且属性=属性值的节点的"B"子节点。 假设当前test2.xml文件如下:

John

10

Jane

15

Peter

20

Nancy

25

Bob

30

Jobs

33

Andy

38

Lee

40

使用xpath进行筛选

//创建xml文档

XmlDocument xmldoc = new XmlDocument();

xmldoc.Load("test2.xml");

Console.WriteLine("选择节点");

XPathNodeIterator iterator1 = xmldoc.CreateNavigator().Select("//root/*");

while (iterator1.MoveNext())

{

XPathNavigator navigator = iterator1.Current;

Console.WriteLine(navigator.OuterXml);

}

Console.WriteLine("选择节点+条件");

XPathNodeIterator iterator2 = xmldoc.CreateNavigator().Select("//root/*[age>10 and age<30]");

while (iterator2.MoveNext())

{

XPathNavigator navigator = iterator2.Current;

Console.WriteLine(navigator.OuterXml);

}

Console.WriteLine("筛选包含命名空间前缀节点");

//筛选包含命名空间前缀节点,需要定义好命名空间,作为参数传入筛选器,否则筛选器无法识别命名空间

XmlNamespaceManager company = new XmlNamespaceManager(xmldoc.NameTable);

company.AddNamespace("companya", "http://www.example.com/companya");

company.AddNamespace("companyb", "http://www.example.com/companyb");

XPathNodeIterator iterator3 = xmldoc.CreateNavigator().Select("//companya:customer1", company);

while (iterator3.MoveNext())

{

XPathNavigator navigator = iterator3.Current;

Console.WriteLine(navigator.OuterXml);

}

Console.WriteLine("筛选包含命名空间前缀节点+条件");

XPathNodeIterator iterator4 = xmldoc.CreateNavigator().Select("//companya:customer1[contains(name,'o')]", company);

while (iterator4.MoveNext())

{

XPathNavigator navigator = iterator4.Current;

Console.WriteLine(navigator.OuterXml);

}

运行结果如下:

选择节点

John

10

Jane

15

Peter

20

Nancy

25

Bob

30

Jobs

33

Andy

38

Lee

40

选择节点+条件

Jane

15

Peter

20

Nancy

25

筛选包含命名空间前缀节点

John

10

Jane

15

筛选包含命名空间前缀节点+条件

John

10

5、C#实现XML配置文件的读写

(1)创建一个XML配置文件

Red

(2)实现读写帮助类

using System.Xml;

namespace MyXML

{

public class XmlConfigHelper

{

///

/// 获取值

///

///

///

///

public static string GetValue(string xmlFilePath,string key)

{

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.Load(xmlFilePath);

XmlNode valueNode = xmlDoc.SelectSingleNode($"/Config/Item[@Key='{key}']");

if (valueNode != null)

{

return valueNode.InnerText;

}

return null;

}

///

/// 设置值,没有新增

///

///

///

///

public static void SetValue(string xmlFilePath, string key, string value)

{

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.Load(xmlFilePath);

XmlNode valueNode = xmlDoc.SelectSingleNode($"/Config/Item[@Key='{key}']");

if (valueNode != null)

{

valueNode.InnerText = value;

}

else

{

XmlElement newElement = xmlDoc.CreateElement("Item");

newElement.SetAttribute("Key", key);

newElement.InnerText = value;

xmlDoc.SelectSingleNode("/Config").AppendChild(newElement);

}

xmlDoc.Save(xmlFilePath);

}

///

/// 判断是否有key

///

///

///

///

public static bool HasKey(string xmlFilePath, string key)

{

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.Load(xmlFilePath);

XmlNode valueNode = xmlDoc.SelectSingleNode($"/Config/Item[@Key='{key}']");

return valueNode != null;

}

///

/// 删除key

///

///

///

public static void DeleteKey(string xmlFilePath, string key)

{

XmlDocument xmlDoc = new XmlDocument();

xmlDoc.Load(xmlFilePath);

XmlNode valueNode = xmlDoc.SelectSingleNode($"/Config/Item[@Key='{key}']");

if (valueNode != null)

{

xmlDoc.SelectSingleNode("/Config").RemoveChild(valueNode);

}

xmlDoc.Save(xmlFilePath);

}

}

}

(3)调用帮助类读写配置

Console.WriteLine("读取配置");

Console.WriteLine($"Color:{XmlConfigHelper.GetValue("config.xml", "Color")}");//Red

Console.WriteLine("设置配置");

XmlConfigHelper.SetValue("config.xml", "Color","Green");

Console.WriteLine($"Color:{XmlConfigHelper.GetValue("config.xml", "Color")}");//Green

XmlConfigHelper.SetValue("config.xml", "Color", "Red");

Console.WriteLine("添加配置");

Console.WriteLine($"Has NewColor:{XmlConfigHelper.HasKey("config.xml", "NewColor")}");//False

XmlConfigHelper.SetValue("config.xml", "NewColor", "Green");

Console.WriteLine($"NewColor:{XmlConfigHelper.GetValue("config.xml", "NewColor")}");//Green

Console.WriteLine("删除配置");

Console.WriteLine($"Has NewColor:{XmlConfigHelper.HasKey("config.xml", "NewColor")}");//True

XmlConfigHelper.DeleteKey("config.xml", "NewColor");

Console.WriteLine($"Has NewColor:{XmlConfigHelper.HasKey("config.xml", "NewColor")}");//False

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: