LINQ to XML
前面也提到过一点LINQ to XML
LINQ to XML是LINQ系列技术中的一种,它主要用来处理XML结构的数据。LINQ to XML提供了修改文档对象模型的内存文档和支持LINQ查询表达式等功能,以及处理XML文档的全新的编程接口。LINQ to XML可以将XML文档保存在内存中,并对内存中的XML文档进行查询,修改操作,以及将内存中的XML文档另存为XML文件。LINQ to XML与传统的DOM的最大不同之处在于:LINQ to XML提供了一种新的轻量级的对象模型。LINQ to XML查询XML文档的查询表达式与XPath在语法上不同,但它们提供相似的功能。
LINQ to XML可以对XML文档实现以下功能或操作:
1.读取XML文档的内容
2.XML文档的序列化操作
3.使用函数更加简单方便地从头开始创建一个新的XML文档
4.使用LINQ更加简单方便地查询XML文档
5.添加,修改,删除XML文档中的元素,属性等信息
6.使用XSD验证XML文档
现在我们来学习一下使用函数构造(是指在单个语句中创建XML元素(或文档或属性等))的方式来创建XML元素(或文档或属性等)。LINQ to XML中的XElement有一种构造函数的参数为数据类型为Object的params数组,因此该函数可以使用任意数量任意类型的参数。XDocument构造函数也是如此。
用函数在内存中构造XML文档,然后通过XDocument的Save()方法保存到指定目录里:
protected void Button1_Click(object sender, EventArgs e)
{
string xmlpath = Server.MapPath("../XML");
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("我是整个文档的注释"),
new XElement("Class",
new XComment("我是Class节点的注释"),
new XElement("Student", new XAttribute("属性名", "属性值"), new XElement("ID", "001"), new XElement("Name", "张三"), new XElement("Age", "23")),
new XElement("Student", new XAttribute("属性名", "属性值"), new XElement("ID", "002"), new XElement("Name", "李四"), new XElement("Age", "24"))
)
);
doc.Save(xmlpath+"/"+"myxml.xml");
Response.ContentType = "text/xml";
Response.Write(doc);
Response.End();
}
看起来比较麻烦,颜色的是XDocument的直接参数,颜色的是代表根节点的XElement的直接参数,颜色的是代表两个子节点的XElement的直接参数
我们来看一下其保存的XML文档就明白了:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--我是整个文档的注释-->
<Class>
<!--我是Class节点的注释-->
<Student 属性名="属性值">
<ID>001</ID>
<Name>张三</Name>
<Age>23</Age>
</Student>
<Student 属性名="属性值">
<ID>002</ID>
<Name>李四</Name>
<Age>24</Age>
</Student>
</Class>
下面我们来了解一下这些LINQ to XML的基础类: using System.Xml.Linq 可参考QLeelulu luckdv
XDocument类表示一个XML文档
属性有Declaration(文件的XML声明)Root(文件的根元素)DocumentType(文件的文档类型)NodeType(文件的节点类型)等
方法有Load()静态方法导入指定地址的XML文件的内容,并创建为XDocument类实例Save()将XDocument类的实例保存为指定地址的XML文件Parse()读取指定的XML文件,并解释该XML文件中的内容
XDeclaration类表示XML文件中的声明
属性有Version(XML文件的版本)Encoding(XML文件的编码)Standalone(指定XML文件是否独立)
XElement类表示XML文件中的一个元素
属性有Name(元素名称)Value(元素的值)[new XElement("Age","24")中Age就是Name,24就是Value]FirstAttribute(元素的第一个属性)LastAttribute(元素的最后一个属性)HasAttributes(元素是否包含属性)
HasElements(元素是否包含其他元素)IsEmpty(是否为一个空元素)EmptySequence(空的元素集合)等
方法有Load()导入指定地址的XML文件的内容,并创建为XElement类实例Save()将XElement类的实例保存为指定地址的XML文件Parse()读取指定的XML文件,并解释该XML文件中的内容AncestorsAndSelf()自身及其上级元素的集合DescendantsAndSelf()自身及其子元素的集合DescendantNodesAndSelf()自身及其子节点的集合[节点XNode可以是XElement,XComment,XText等]Attribute()根据属性的名称获取该元素内的属性Attributes()获取(也可根据属性名获取)该元素内的所有属性GetDefaultNamespace()元素的默认命名空间ReplaceAll()替换该元素自动的属性RemoveAll()移除该元素的所有内容ReplaceAttributes()替换该元素的所有属性RemoveAttributes()移除该元素的所有属性SetValue()设置该元素的值SetAttributeValue()设置该元素的属性的值SetElementValue()设置该元素的子元素的值
XAttribute类表示XML文件中的属性
属性有
Name(属性名称)
Value(属性值)
NextAttribute(其父元素的下一个属性)
PreviousAttribute(其父元素的上一个属性)
NodeType(属性节点的节点类型)
IsNamespaceDeclaration(表示该属性是否为命名空间的声明)
EmptySequence(空的属性的集合)
方法有
Remove(从其父元素中移除该属性)
SetValue(设置该属性的值)
XComment类表示XML文件中的一个注释
属性有NodeType(注释节点的节点类型)Value(注释的内容)
XNamespace类表示XML文件中的一个
命名空间
先创建一个XML文件
protected void Button2_Click(object sender, EventArgs e)
{
string xmlpath = Server.MapPath("../XML");
XDocument doc = new XDocument(new XDeclaration("1.0","uff-8","yes"),new XComment("this is a xml comment"),
new XElement("Class",new XAttribute("NO","1"),
new XElement("Student",new XComment("this is a student"),
new XElement("Name","王小虎"),
new XElement("Age","20")
),
new XElement("Student",
new XElement("Name","王小龙"),
new XElement("Name","王小豹"),
new XElement("Age","22")
)
)
);
doc.Save(xmlpath + "/" + "xmldoc.xml");
}
查询根元素
protected void Button3_Click(object sender, EventArgs e)
{
string xmlpath = Server.MapPath("../XML");
XDocument doc = XDocument.Load(xmlpath + "/" + "xmldoc.xml");
var result1 = doc.Root;
Label3.Text ="doc.Root"+result1.Name;
-------------------------------还可以--------------------------------
string xmlpath = Server.MapPath("../XML");
使用XElement的Load方法返回的XElement实例就是该XML文件的根元素
XElement root = XElement.Load(xmlpath + "/" + "xmldoc.xml");
Label3.Text = root.Name;
}
查询当前元素下(或指定元素名)的子元素
protected void Button3_Click(object sender, EventArgs e)
{
--------------------------Elements()------------------------------
string xmlpath = Server.MapPath("../XML");
XElement root = XElement.Load(xmlpath + "/" + "xmldoc.xml");
查询根元素下所有元素名是Student的子元素下所有元素名是Name的子元素,没参数的话,如root.Elements()查询根元素下的所有子元素(不包括子元素的子元素)
var result = from u in root.Elements("Student").Elements("Name") select u;
结果:result包括的元素有王小虎,王小龙,王小豹
--------------------------Element()-------------------------------
Element()查询的是当前元素下的第一个子元素或当前元素下的第一个符合条件的子元素,貌似只能在select子句里用
string xmlpath = Server.MapPath("../XML");
XElement root = XElement.Load(xmlpath + "/" + "xmldoc.xml");
var result = from u in root.Elements("Student") select u.Element("Name");
结果:result包括的元素有王小虎,王小龙 (可以看出区别,这里没有王小豹)
}
使用LINQPad学习这些轴方法如下图:
Descendants()与Elements()的区别是前者查询的不仅仅是当前元素下的子元素,而是
当前元素下的所有元素(或所有与指定元素名相同的元素,如果有参数的话)。其他类似的有
DescendantsAndSelf()包括当前元素。
DescendantNodes()当前元素下的所有节点XNode,包括注释什么的。
DescendantNodesAndSelf()包括当前元素。
还是根据上面的图片来查询:
查询所有元素名是Age的元素
var result = from u in root.Descendants() where u.Name.ToString()=="Age" select u.Value;
查询所有元素值是22的元素
var result = from u in root.Descendants() where u.Value=="22" select u.Value;
查询所有type属性值是str的元素 Attributes()返回当前元素内的指定属性元素 Parent属性返回当前元素的父元素
var result = from u in root.Descendants().Attributes("type") where u.Value=="str" select u.Parent;
将所有元素名是Age的元素按 降序排列, 然后查询的是Age元素的
上一个同级元素
var result = from u in root.Descendants("Age") orderby u.Value descending select u.PreviousNode;
查询所有元素名是Age的元素 然后利用查询操作计算出这些元素的值的平均值
var result = from u in root.Descendants("Age") orderby u.Value descending select u;
var avg=result.Average(u=>int.Parse(u.Value));
LINQ to XML操作XML文件
先用LINQPad创建一个XML文件,如下图:
添加元素
XElement root=XElement.Load("D:\\linq\\xml.xml");
XElement student=new XElement("Student",
先构造出一个元素
new XElement("Name","王小蛇"),
new XElement("Age","23")
);
root.Add(student);
这里是在根元素下添加这个元素 Add()添加的元素将作为前面元素(这里是root)的子元素
root.Save("D:\\linq\\xml.xml");
XElement root=XElement.Load("D:\\linq\\xml.xml");
XElement name=new XElement("Name","王小猪");
构造出一个元素
var result=from u in root.Elements("Student").Elements("Name") where u.Value=="王小虎" select u;
foreach(var item in result)
{
item.AddAfterSelf(name);
在当前元素的后面添加这个元素 AddAfterSelf()添加的元素作为前面元素的兄弟元素
}
root.Save("D:\\linq\\xml.xml");
其他类似的:
AddBeforeSelf()在前面添加兄弟元素 AddFirst()添加的元素将作为前面元素的第一个子元素
修改元素
XElement root=XElement.Load("D:\\linq\\xml.xml");
XElement name=new XElement("Name","王小猪");
var result=from u in root.Elements("Student").Elements("Name") where u.Value=="王小虎" select u;
foreach(var item in result)
{
item.SetValue("王小猴");
设置当前元素的值
}
root.Save("D:\\linq\\xml.xml");
XElement root=XElement.Load("D:\\linq\\xml.xml");
XElement student=new XElement("Student",
构造要用来替换指定元素的元素
new XElement("Name",
new XAttribute("type","int"),"王老虎"),
new XElement("Age","22")
);
var result=from u in root.Elements("Student").Elements("Name") where u.Value=="王小虎" select u.Parent;
foreach(var item in result)
{
item.ReplaceWith(student);
ReplaceWith()用指定元素替换某元素
}
root.Save("D:\\linq\\xml.xml");
其他类似的:
ReplaceNodes()用某元素替换指定元素的子元素
XElement root=XElement.Load("D:\\linq\\xml.xml");
var result=from u in root.Elements("Student").Elements("Name") where u.Value=="王小虎" select u;
foreach(var item in result)
{
item.SetAttributeValue("type","int");
设置当前元素的属性名及属性值
}
root.Save("D:\\linq\\xml.xml");
删除元素
XElement root=XElement.Load("D:\\linq\\xml.xml");
var result=from u in root.Elements("Student").Elements("Name") where u.Value=="王小豹" select u;
foreach(var item in result)
{
item.Remove();
删除当前元素
}
root.Save("D:\\linq\\xml.xml");
其他类似的:
RemoveAll()将当前元素的所有子元素删除 RemoveAttributes删除当前元素的属性元素