一. 使用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》