您的位置:首页 > 其它

Linq To XML 学习

2007-07-02 13:50 555 查看
这几天抽空看了看C#3.0的一些新特性,匿名对象、Lambda表达式、Linq等,给我很大的冲击。简洁化、人性化、更加可读易理解的代码,让C#3.0增色不少。以前我总认为C#语言就是followJava语言,现在看来微软就是强大,在流行的基础上创出了自己的个性,漂亮简洁高效的编程语言让人不得不倾心。

因为以前的项目用到Xml操作比较多,我着重看了看LinqToXml,用msdn上的话来说,LinqToXml是LINQ项目的一个组件,它是一种现代化的、在内存中的XML编程API,吸取了最新的.NET框架语言创新的优点(比如使用泛型、可空类型),它提供全新的、轻量的、高效的API操作。有兴趣的人可以参考这篇文章:.NETlanguage-IntegratedQueryforXMLData。下面看看它到底有哪些吸引人之处。

如果我们要生成这样一种XML:

<people>
<person>
<firstname>Bob</firstname>
<lastname>Willam</lastname>
<age>50</age>
<phonetype="mobile">012345</phone>
<phonetype="home">987654</phone>
<address>
<country>USA</country>
<city>LA</city>
</address>
</person>
....
</people>

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

使用XmlDocument来生成这样一段XML数据,大概是下面这样:

XmlDocumentdoc=newXmlDocument();
XmlElementfirstname=doc.CreateElement("firstname");
firstname.InnerText="Bob";
XmlElementlastname=doc.CreateElement("lastname");
lastname.InnerText="Willam";
XmlElementage=doc.CreateElement("age");
age.InnerText="50";
XmlElementphone1=doc.CreateElement("phone");
phone1.SetAttribute("type","mobile");
phone1.InnerText="012345";
XmlElementphone2=doc.CreateElement("phone");
phone2.SetAttribute("type","home");
phone2.InnerText="987654";
XmlElementcountry=doc.CreateElement("country");
country.InnerText="USA";
XmlElementcity=doc.CreateElement("city");
city.InnerText="LA";
XmlElementaddress=doc.CreateElement("address");
address.AppendChild(country);
address.AppendChild(city);
XmlElementperson=doc.CreateElement("person");
person.AppendChild(firstname);
person.AppendChild(lastname);
person.AppendChild(age);
person.AppendChild(phone1);
person.AppendChild(phone2);
person.AppendChild(address);
XmlElementpeople=doc.CreateElement("people");
people.AppendChild(person);
doc.AppendChild(people);

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

这段代码看上去杂乱无章,看久了头晕,毫无美观可言。一般情况下会对XmlDocument的API进行封装,减少重复代码:

XmlElementfirstname=XmlUtility.MakeElement(doc,"firstname","Bob");
XmlElementlastname=XmlUtility.MakeElement(doc,"lastname","Willam");
...
XmlElementaddress=XmlUtility.MakeElement(doc,"address",
XmlUtility.MakeElement(doc,"country","USA"),
XmlUtility.MakeElement(doc,"city","LA"));
publicclassXmlUtility
....
publicstaticXmlElementMakeElement(XmlDocumentdoc,stringkey,stringvalue)
{
XmlElemente=doc.CreateElement(key);
e.InnerText=value;
returne;
}
publicstaticXmlElementMakeElement(XmlDocumentdoc,stringkey,paramsXmlElement[]values)
{
XmlElemente=doc.CreateElement(key);
foreach(XmlElementvalueinvalues)
e.AppendChild(value);
returne;
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

下面看看怎样用LinqToXml操作API来生成这样一段Xml数据(需要引用System.Xml.Linq程序集):

XElementpeople=
newXElement("people",
newXElement("person",
newXElement("firstname","Bob"),
newXElement("lastname","Willam"),
newXElement("age","50"),
newXElement("phone","012345",
newXAttribute("type","mobile")),
newXElement("phone","987654",
newXAttribute("type","home")),
newXElement("address",
newXElement("country","USA"),
newXElement("city","LA")
)
)
);


这样的代码简洁直观,构造方法加上良好的缩进,让人可以很容易看懂该Xml的结构层次。

用上Linq以后,查询Xml也很简单,比如:

XDocumentdoc=XDocument.Load(@"peopleData.xml");
varfoundPeople=doc.Descendants("person")
.Where(p=>Convert.ToInt32(p.Element("age").Value)>20)
.Select(p=>new
{
Name=p.Element("firstname").Value+""
+p.Element("lastname").Value,
Age=Convert.ToInt32(p.Element("age").Value),
Phone=p.Elements("phone").Select(ph=>ph.Value).ToArray(),
}
);
foreach(varpersoninfoundPeople)
{
//person.Name
//person.Age
//person.Phone....
}


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

我们再来看看LinqToXml是怎样加载Xml呢?

在c#2.0里面加载Xml数据都是通过XmlDocument来操作,比如:

stringxmlContent="...";
XmlDocumentxmlDoc=newXmlDocument();
xmlDoc.LoadXml(xmlContent);

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

或者从文件中加载:

xmlDoc.Load(@"D:\test.xml");

而LinqToXml摒弃了必须利用Document操作,可以直接用XElement的Load或Parse方法

stringxmlContent="...";
XElementxmlFromString=XElement.Parse(xmlContent);

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

或者
XElementxmlFromFile=XElement.Load(@"D:\test.xml");//当然Load有多个重载方法,比如从Reader中加载等等

LinqToXml提供了简洁并且人性化的API,使得程序员对XML元素的操作更加直观、自然,最大的改变是摒弃了通过XmlDocument操作XML元素,在2.0及以前的时代,XMLdocument是作为XML文档树的容器而存在的,XML的各种节点,包括Element,Attribute等都必须通过XMLdocument的上下文来创建:

XmlDocumentxmlDoc=newXmlDocument();
XmlElementperson=xmlDoc.CreateElement("person");
XmlAttributeatt=xmlDoc.CreateAttribute("age");

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}


通过XMLdocument上下文创建的元素等只能存在于该上下文中,如果另外一个XMLdocument想要使用这些元素,必须ImportNode,在LinqToXml中没有这样烦琐的操作和注意事项,一切都是以最自然最人性化的方式进行:

XElementperson=newXElement("person");
XAttributeage=newXAttribute("age","50");

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

这里并没有提供XAttribute(stringname)的构造函数,恐怕是考虑到Attribute必须有值吧,才给了这个约束。

当然,如果有需要的话,在LinqToXml中也可以使用XMLDocument,比如在XMLdocument中需要添加声明等等。

XDocumentxmlDoc=
newXDocument(
newXDeclaration("1.0","utf-8","yes"),
newXComment("Thisisthecomments"),
newXProcessingInstruction("test","testprocessinginstruction"),
newXElement("people")
);

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: