概念
XML是一种标记语言,和HTML一样
XML基础
用法
- 开始标签从一个左尖括号开始,后面跟元素名,紧接着是可选的特性,最后是右尖括号。
- 关闭标签从一个左尖括号开始,后面是斜杠,然后是元素名和右尖括号。
- 没有内容的元素可以直接由单个标签表示,从左尖括号开始,后面是元素名和斜杠,并以右尖括号结束。
例
<EmployeeName>Sally Jones</EmployeeName>
规则
- XML文档必须有一个根元素来包含所有其他元素。XML标签必须合理嵌套。
- 与HTML标签不同,XML标签是区分大小写的。
- XML特性是名字/值的配对,它包含了元素的额外元数据。特性的值部分必须包含在引号内,可以是单引号也可以是双引号。
- XML文档中的空格是有效的。这与把空格作为单个空格输出的HTML不同。
实例
Employees根节点,包含两个Employees类型子节点
<Employees>
<Employee>
<Name>Bob Smith</Name>
<PhoneNumber>408-555-1000</PhoneNumber>
</Employee>
<Employee>
<Name>Sally Jones</Name>
<PhoneNumber>415-555-2000</PhoneNumber>
<PhoneNumber>415-555-2001</PhoneNumber>
</Employee>
</Employees>
XML类
XElement、XAttribute、XDocument
- 可作为XDocument节点的直接子节点
- 大多数情况下,下面的每一个节点类型各有一个:XDeclaration节点、XDocumentType节点以及XElement节点。
- 任何数量的XProcessingInstruction节点。
- 如果在XDocument中有最高级别的XElement节点,那么它就是XML树中其他元素的根。
- 根元素就可以包含任意数量的嵌套XElement、XComment或XProcessingInstruction节点,在任何级别上嵌套。
创建、保存、加载和显示XML文档
引入命名空间:using System.Xml.Linq;
从创建一个简单的包含名称为Employees节点的XML树开始,两个子节点包含两个职员的名字。
创建树之后,代码使用XDocument的Save方法把它保存在一个叫做EmployeesFile.xml的文件中。然后,再使用XDocument的Load静态方法把XML树从文件中重新读回,并把树赋值给一个新的XDocument对象。最后,使用writeLine把新的XDocument对象保存的树结构显示出来。
XDocument employees1 =
new XDocument( //创建XML文档
new XElement("Employees", //创建根元素
new XElement("Name", "Bob Smith"), //创建元素
new XElement("Name", "Sally Jones") //创建元素
)
);
employees1.Save("EmployeesFile.xml"); //保存文件
//将保存的文档加载到新变量中
XDocument employees2 = XDocument.Load("EmployeesFile.xml");
Console.WriteLine(employees2);
结果
<Employees>
<Name>Bob Smith</Name>
<Name>Sally Jones</Name>
</Employees>
分析
创建文档是:XDocument类
创建元素是:XElement类
创建XML树
XDocument和XElement两个构造函数
- 第一个参数都是对象名;
- 第二个参数以及之后的参数包含了XML树的节点。构造函数的第二个参数是一个param参数,也就是说可以有任意多的参数。
例
XDocument employeeDoc =
new XDocument( //创建XML文档
new XElement("Employees", //创建根元素
new XElement("Employee", //第一个Employee元素
new XElement("Name", "Bob Smith"), //创建元素
new XElement("PhoneNumer", "408-555-1000")), //创建元素
new XElement("Employee", //第二个Employee元素
new XElement("Name", "Sally Jones"), //创建元素
new XElement("PhoneNumer", "415-555-5000"),
new XElement("PhoneNumer", "415-555-5001"))) //创建元素
);
Console.WriteLine(employeeDoc);
结果
<Employees>
<Employee>
<Name>Bob Smith</Name>
<PhoneNumer>408-555-1000</PhoneNumer>
</Employee>
<Employee>
<Name>Sally Jones</Name>
<PhoneNumer>415-555-5000</PhoneNumer>
<PhoneNumer>415-555-5001</PhoneNumer>
</Employee>
</Employees>
XML树的值
方法名称 | 类 | 返回类型 | 描述 |
---|---|---|---|
Nodes | Xdocument | IEnumerable | 返回当前节点的所有子节点(不管是什么类型) |
Elements | Xdocument、XElement | IEnumerable | 返回当前节点的XElement子节点,或所有具有某个名字的子节点 |
Element | Xdocument、XElement | XElement | 返回当前节点的第一个XElement子节点,或具有某个名字的子节点 |
Descendants | XElement | IEnumerable | 返回所有的XElement子代节点,或所有具有某个名字的XElement子代节点,不管它们处于当前节点下嵌套的什么层次 |
DescendantsAndSelf | XElement | IEnumerable | 和IDescendants一样,但是包括当前节点 |
Ancestors | XElement | IEnumerable | 返回所有上级XElement节点,或者所有具有某个名字的上级XElement节点 |
AncestorsAndSelf | XElement | IEnumerable | 和IAncestors一样,但是包括当前节点 |
Parent | xElement | XElement | 返回当前节点的父节点 |
注意
Nodes: Nodes方法返回IEnumerablecobject>类型的对象,因为返回的节点可能是不同的类型,比如XElement、XComment等。我们可以使用以类型作为参数的方法ofType(type)来指定返回某个类型的节点。
例如,如下代码只获取XComment节点:IEnumerable<XComments comments = xd.Nodes().0fType<XComment>();
Elements:由于获取XElements是一个非常普遍的需求,就出现了Nodes.0fType(XElement)()表达式的简短形式——Elements方法。
- 使用无参数的Elements方法返回所有子XElements。
- 使用单个name参数的Elements方法只返回具有这个名字的子XElements。例如,如下代码行返回所有具有名字PhoneNumber的子XElement节点。
IEnumerable<XElement> empPhones = emp.Elements("PhoneNumber");
Element:这个方法只获取当前节点的第一个子XElement。与Elements方法相似,它可以带一个参数或不带参数调用。如果没有参数,获取第一个子XElement节点。如果带一个参数,它获取第一个具有那个名字的子XElement。
Descendants和Ancestors:这些方法和Elements以及Parent方法差不多,只不过它们不返回直接的子元素或父元素,而是忽略嵌套级别,包括所有之下或者之上的节点。
例
XDocument employeeDoc =
new XDocument( //创建XML文档
new XElement("Employees", //创建根元素
new XElement("Employee", //第一个Employee元素
new XElement("Name", "Bob Smith"), //创建元素
new XElement("PhoneNumer", "408-555-1000")), //创建元素
new XElement("Employee", //第二个Employee元素
new XElement("Name", "Sally Jones"), //创建元素
new XElement("PhoneNumer", "415-555-5000"),
new XElement("PhoneNumer", "415-555-5001"))) //创建元素
);
XElement root = employeeDoc.Element("Employees"); //获取名为"Employees"的子XElement
IEnumerable<XElement> employees = root.Elements();
foreach(XElement emp in employees)
{
XElement empNameNode = emp.Element("Name"); //获取名为"Name"的子XElement
Console.WriteLine(empNameNode.Value);
IEnumerable<XElement> empPhones = emp.Elements("PhoneNumer"); //获取Employees节点下所有的Employees
foreach(XElement phone in empPhones)
{
Console.WriteLine($" {phone.Value}");
}
}
结果
Bob Smith
408-555-1000
Sally Jones
415-555-5000
415-555-5001
添加节点及操作XML
使用Add为现有元素添加子元素,可依次添加多个
实例
XDocument xd = new XDocument( //创建XML树
new XElement("root",
new XElement("first")));
Console.WriteLine("初始树");
Console.WriteLine(xd);
XElement rt = xd.Element("root"); //获取第一个元素
rt.Add(new XElement("second")); //添加子元素
rt.Add(new XElement("third"), //添加3个子元素
new XElement("ImportantComment"),
new XElement("fourth"));
Console.WriteLine("添加子元素后的树");
Console.WriteLine(xd);
Console.ReadKey();
结果
初始树
<root>
<first />
</root>
添加子元素后的树
<root>
<first />
<second />
<third />
<ImportantComment />
<fourth />
</root>
操作XML方法
方法名称 | 从哪里调用 | 描述 |
---|---|---|
Add | 父节点 | 在当前节点的既有子节点后增加新的子节点 |
AddFirst | 父节点 | 在当前节点的既有子节点前增加新的子节点 |
AddBeforeSelf | 节点 | 在同级别的当前节点之前增加新的节点 |
AddAfterself | 节点 | 在同级别的当前节点之后增加新的节点 |
Remove | 节点 | 删除当前所选的节点及其内容 |
RemoveNodes | 节点 | 删除当前所选的XElement及其内容 |
SetElement | 父节点 | 设置节点的内容 |
ReplaceContent | 节点 | 替换节点的内容 |
使用XML特性
用于提供XElement节点的额外信息,放在XML元素的开始标签中
当我们以函数方法构造XML树时,可以只需要在XElement的构造函数中包含xAttribute构造函数来增加特性
XAttribute构造函数有两种形式,一种是接受name和value,另一种是接受现有XAttribute的引用。
例
XDocument xd = new XDocument(
new XElement("root",
new XAttribute("color", "red"), //特性构造函数
new XAttribute("size", "large"),
new XElement("first"),
new XElement("second")));
Console.WriteLine(xd);
结果
<root color="red" size="large">
<first />
<second />
</root>
获取特性
使用Attribute方法
例
XDocument xd = new XDocument(
new XElement("root",
new XAttribute("color", "red"), //特性构造函数
new XAttribute("size", "large"),
new XElement("first"),
new XElement("second")));
Console.WriteLine(xd);
XElement rt = xd.Element("root"); //获取root元素
XAttribute color = rt.Attribute("color"); //获取特性
XAttribute size = rt.Attribute("size");
Console.WriteLine($"color:{color.Value}");
Console.WriteLine($"size:{size.Value}");
结果
<root color="red" size="large">
<first />
<second />
</root>
color:red
size:large
移除特性
使用Remove方法,或在它父节点使用SetAttributeValue方法把特性设置为null
例
XDocument xd = new XDocument(
new XElement("root",
new XAttribute("color", "red"), //特性构造函数
new XAttribute("size", "large"),
new XElement("first"),
new XElement("second")));
XElement rt = xd.Element("root"); //获取root元素
rt.Attribute("color").Remove(); //移除color特性
rt.SetAttributeValue("size", null); //移除size特性
Console.WriteLine(xd);
结果
<root>
<first />
<second />
</root>
改变特性
使用SetAttributeValue方法添加特性或改变特性
例
XDocument xd = new XDocument(
new XElement("root",
new XAttribute("color", "red"), //特性构造函数
new XAttribute("size", "large"),
new XElement("first"),
new XElement("second")));
XElement rt = xd.Element("root"); //获取root元素
rt.SetAttributeValue("size", "medium"); //改变特性
rt.SetAttributeValue("width", "narrow"); //添加特性
Console.WriteLine(xd);
结果
<root color="red" size="medium" width="narrow">
<first />
<second />
</root>
其它类型
XComment
用于XML注释
XML注释由<!--和-->记号之间的文本组成。记号之间的文本会被XML解析器忽略。
例
new XComment("This is a comment");
效果
<!--This is a comment-->
XDeclaration
用来表明XML版本号、使用的字符编码类型以及文档是否依赖外部引用的一行开始,也叫XML声明
例
new XDeclaration("1.0", "utf-8", "yes")
效果
<?xml version="1.o" encoding="utf-8" standalone="yes"?>
XProcessingInstruction
XML处理指令用于提供XML文档如何被使用和翻译的额外数据
接受两个字符串参数:目标和数据串
如果处理指令接受多个数据参数,这些参数必须包含在XProcessingInstruction构造函数的第二个字符串参数中
例
new XProcessingInstruction("xml-stylesheet", @"href=""stories"", type=""text/css""")
效果
<?xml-stylesheet href="stories.css" type="text/css"?>
实例
XDocument xd = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("This is a comment"),
new XProcessingInstruction("xml-stylesheet", @"href=""stories.css"", type=""text/css"""),
new XElement("root",
new XElement("first"),
new XElement("second")));
Console.WriteLine(xd);
结果
<!--This is a comment-->
<?xml-stylesheet href="stories.css", type="text/css"?>
<root>
<first />
<second />
</root>