一. 使用XDocument类:
1. 执行LINQ to XML查询:
XDocument类可以很简单地使用构造器构造,或使用Load或Parse方法来初始对象。下面的代码教你如何使用Parse方法来将XML字符串装载到XDocument对象中。然后将XML文档保存到XDocumentTest.xml文件中去。
private void parseXDocumentToolStripMenuItem_Click( object sender, EventArgs e) { string xml = @" <CustomersOrders> <Customer CustomerID='ALFKI' CompanyName='Alfreds Futterkiste'> <Order OrderID='10643' Freight='29.4600' /> <Order OrderID='10692' Freight='61.0200' /> <Order OrderID='10702' Freight='23.9400' /> <Order OrderID='10835' Freight='69.5300' /> <Order OrderID='10952' Freight='40.4200' /> <Order OrderID='11011' Freight='1.2100' /> </Customer> <Customer CustomerID='ANATR' CompanyName='Ana Trujillo'> <Order OrderID='10308' Freight='1.6100' /> <Order OrderID='10625' Freight='43.9000' /> <Order OrderID='10759' Freight='11.9900' /> <Order OrderID='10926' Freight='39.9200' /> </Customer> <Customer CustomerID='ANTON' CompanyName='Antonio Moreno'> <Order OrderID='10365' Freight='22.0000' /> <Order OrderID='10507' Freight='47.4500' /> <Order OrderID='10535' Freight='15.6400' /> <Order OrderID='10573' Freight='84.8400' /> <Order OrderID='10677' Freight='4.0300' /> <Order OrderID='10682' Freight='36.1300' /> <Order OrderID='10856' Freight='58.4300' /> </Customer> <Customer CustomerID='AROUT' CompanyName='Around the Horn'> <Order OrderID='10355' Freight='41.9500' /> <Order OrderID='10383' Freight='34.2400' /> <Order OrderID='10453' Freight='25.3600' /> <Order OrderID='10558' Freight='72.9700' /> <Order OrderID='10707' Freight='21.7400' /> <Order OrderID='10741' Freight='10.9600' /> <Order OrderID='10743' Freight='23.7200' /> <Order OrderID='10768' Freight='146.3200' /> <Order OrderID='10793' Freight='4.5200' /> <Order OrderID='10864' Freight='3.0400' /> <Order OrderID='10920' Freight='29.6100' /> <Order OrderID='10953' Freight='23.7200' /> <Order OrderID='11016' Freight='33.8000' /> </Customer> </CustomersOrders> "; var doc = XDocument.Parse(xml); doc.Save(getFilePath("XDocumentTest.xml")); MessageBox.Show("XDocument Saved"); }
下面的这段代码使用Load方法来初始XDocument对象。XML的内容还是与前面的例子一样。我们要查找出order ID 10677的customer ID和它的freight。
private void lINQQueryToolStripMenuItem_Click( object sender, EventArgs e) { var doc = XDocument.Load(getFilePath("XDocumentTest.xml")); var result = (from order in doc.Descendants("Order") where order.Attribute("OrderID").Value == "10677" select new { OrderID = (int)order.Attribute("OrderID"), CustomerID = (string)order.Parent.Attribute("CustomerID"), Freight = (decimal)order.Attribute("Freight") }).FirstOrDefault(); txtLog.Text = string.Format("OrderID:{0} CustomerID:{1} Freight:{2:C}", result.OrderID, result.CustomerID, result.Freight); }
2.使用LINQ to XML聚合运算(Aggregate):
如果你想查询每个客户的freight的总和,你可以向下面的代码这样使用LINQ to XML。
private void lINQQuerySumToolStripMenuItem_Click( object sender, EventArgs e) { var doc = XDocument.Load(getFilePath("XDocumentTest.xml")); var result = from customer in doc.Descendants("Customer") select new { CustomerID = (string)customer.Attribute("CustomerID"), TotalFreight = customer.Descendants("Order") .Sum(o => (decimal)o.Attribute("Freight")) }; txtLog.Clear(); foreach (var customer in result) { txtLog.AppendText(string.Format("CustomerID:{0} TotalFreight:{1,8:C}\r\n", customer.CustomerID, customer.TotalFreight)); } }
3.使用LINQ to XML Join:
Join可以用在LINQ to XML和其他的LINQ providers,比如说LINQ to Objects。下面的代码展示了如何将一个数组和一个XML文件Join起来。
private void lINQQueryJoinToolStripMenuItem_Click( object sender, EventArgs e) { string[] orders = { "10707", "10835", "10953" }; var doc = XDocument.Load(getFilePath("XDocumentTest.xml")); var result = from order in doc.Descendants("Order") join selected in orders on (string)order.Attribute("OrderID") equals selected select new { OrderID = (int)order.Attribute("OrderID"), CustomerID = (string)order.Parent.Attribute("CustomerID"), Freight = (decimal)order.Attribute("Freight") }; txtLog.Clear(); foreach (var order in result) { txtLog.AppendText( string.Format("OrderID:{0} CustomerID:{1} Freight:{2:C}\r\n", order.OrderID, order.CustomerID, order.Freight)); } }
4.使用LINQ to XML 命名空间:
LINQ to XML支持使用命名空间。就象.NET框架命名空间一样,XML命名空间也是为了避免命名冲突,尤其是当将多个XML文档合并的时候,很有可能有同样名字的结点代表着不同的含义。比如说,一个Title元素在对一本书而言和对一个人而言的时候,含义是不同的。下面的这段代码演示了如何使用处理一个包含命名空间的XML文档。
private void lINQQueryNamespaceToolStripMenuItem_Click( object sender, EventArgs e) { var xml = @"<Root xmlns:aw='http://www.adventure-works.com' xmlns='http://www.xyz.com'> <Child>1</Child> <aw:Child>2</aw:Child> <Child>3</Child> <aw:Child>4</aw:Child> <Child>5</Child> <aw:Child>6</aw:Child> </Root>"; var doc = XDocument.Parse(xml); txtLog.Clear(); var result1 = from c in doc.Descendants("Child") select c; txtLog.AppendText("Query for Child\r\n"); foreach (var xElement in result1) { txtLog.AppendText((string)xElement + "\r\n"); } var aw = XNamespace.Get("http://www.adventure-works.com"); var result2 = from c in doc.Descendants(aw + "Child") select c; txtLog.AppendText("Query for aw+Child\r\n"); foreach (var xElement in result2) { txtLog.AppendText((string)xElement + "\r\n"); } var defaultns = XNamespace.Get("http://www.xyz.com"); var result3 = from c in doc.Descendants(defaultns + "Child") select c; txtLog.AppendText("Query for defaultns+Child\r\n"); foreach (var xElement in result3) { txtLog.AppendText((string)xElement + "\r\n"); } txtLog.AppendText("Done\r\n"); }
二.使用LINQ to XML 对XML进行变换:
1. 将XML变换为Object:
下面的例子将XML变换为IEnumerable<Customer>和IEnumerable<Order>。
private void transformToObjectsToolStripMenuItem_Click( object sender, EventArgs e) { var doc = XDocument.Load(getFilePath("XDocumentTest.xml")); var customersOrders = from c in doc.Descendants("Customer") select new Customer { Id = (string)c.Attribute("CustomerID"), Name = (string)c.Attribute("CompanyName"), Orders = (from o in c.Elements("Order") select new Order { Id = (int)o.Attribute("OrderID"), Freight = (decimal)o.Attribute("Freight") }).ToList() }; txtLog.Clear(); foreach (var c in customersOrders) { txtLog.AppendText( String.Format("ID:{0} Name:{1}\r\n", c.Id, c.Name)); foreach (var o in c.Orders) { txtLog.AppendText( String.Format(" OrderID:{0} Freight:{1,7:C}\r\n", o.Id, o.Freight)); } } }
2. 将XML变换为Text:
下面的例子将XML变换为IEnumerable<String>。
private void transformToTextToolStripMenuItem_Click( object sender, EventArgs e) { var doc = XDocument.Load(getFilePath("XDocumentTest.xml")); var customersOrders = from c in doc.Descendants("Customer") select new { CustomerInfo = string.Format( "ID:{0} Name:{1}\r\n", c.Attribute("CustomerID"), c.Attribute("Name")), OrderInfo = from o in c.Elements("Order") select string.Format( " OrderID:{0} Freight:{1,7:C}\r\n", (int)o.Attribute("OrderID"), (decimal)o.Attribute("Freight")) }; foreach (var c in customersOrders) { txtLog.AppendText(c.CustomerInfo); foreach (var o in c.OrderInfo) { txtLog.AppendText(o); } } }
3. 将XML变换为其他XML:
你也可以使用LINQ to XML来将一个XML变换为另一种格式的XML文档。如果你使用Visual Basic的XML literals的话,将非常的简便。不过下面的例子还是使用C#来演示是如何将一个XML变换为其他格式的XML的。
private void transformXMLToXMLToolStripMenuItem_Click( object sender, EventArgs e) { var doc = XDocument.Load(getFilePath("XDocumentTest.xml")); var newXml = new XDocument( new XElement("root", from o in doc.Descendants("Order") select new XElement("Order", new XAttribute("CustID", o.Parent.Attribute("CustomerID").Value), new XAttribute("CustName", o.Parent.Attribute("CompanyName").Value), new XAttribute("OrdID", o.Attribute("OrderID").Value), new XAttribute("OrdFreight", o.Attribute("Freight").Value) ) ) ); txtLog.Text = newXml.ToString(); }
三. 小结:
1. XDocument提供了对XML文档in-memory,随机的读和写操作。
2. XDocument使用LINQ to XML来读取XML结点。
3. 当使用XAttribute对象时,你可以使用CType(C#显式转换 explicit cast)语句来把属性值转换为你想要的类型。
4. 当使用XElement对象时,你可以使用CType(C#显式转换 explicit cast)语句来把属性值转换为你想要的类型。
5. XDocument和XElement都提供了一个Load方法来从一个XmlReader文件进行装载。
6. XDocument和XElement都提供了构造器。你可以把代表XML内容的XNode传递给构造器进行构造。
7. XDocument和XElement都提供了一个Parse方法。你可以把XML字符串传递进来。
8. 你可以通过LINQ投射(projection)来将XML变换为Object。
9. LINQ投射可以将XML变换为IEnumerable<String>。
10. LINQ投射可以将XML变换为其他格式的XML。
11. 如果你使用Visual Basic,你可以使用XML literals来简化变化过程。
原文出自《Access Data with Microsoft .NET Framework 4》