LINQ to XML 轴
定义:
创建XML树或将XML文档加载到XML树之后,可以进行查询,从而查找元素并检索它们的值。
两类轴方法:
-一些轴就是XELement和XDocument类中返回IEnumerable(T)集合的方法。
-另一些轴方法是Extensions类中的扩展方法。实现为扩展方法的轴对集合进行操作,然后返回集合。
XContainer是XElement的基类!
-常见的轴方法:
-XContainer.Elements()返回集合
-XContainer.Descendants()返回集合
-XContainer.Element()返回单个元素
-XElement.Attribute(XName)返回单个属性
-XElement.Attributes(XName)返回所有属性集合
下面是XElement类(或其基类)的方法汇总,可以对XElement调用这些方法以返回元素集合
-XNode.Ancestors 返回此元素的上级的XElement的IEnumerable(T)
-XContainer.Descendants 返回此元素的子代的XElement的IEnumerable(T)
-XContainer.Elements 返回此元素的子元素XElement的IEnumerable(T)
-XNode.ElementsAfterSelf 返回此元素之后的元素的XElement的IEnumerable(T)
-XNode.ElementsBeforeSelf 返回此元素之前的元素的XElement的IEnumerable(T)
-XElement.AncestorsAndSelf 返回此元素及其上级的XElement的IEnumerable(T)
-XElementDescendantsAndSelf 返回此元素及其子代的XElement的IEnumerable(T)
如何获取元素的值,有两种主要方法可以完成此操作
– 一种方法是将XElement 或XAttribute 强制转换为所需的类型。然后,显式转换运算符将元素或属性的内容转换为指定的类型,并将其分配给变量。
– 此外,还可以使用XElement.Value 属性或XAttribute.Value 属性,但是,对于C#,强制转换通常是更好的方法。在检索可能存在也可能不存在的元素(或属性)的值时,如果将元素或属性强制转换为可以为null 的类型,则代码会更易于编写无法通过强制转换设置元素的内容,而通过XElement.Value 属性可以做到这一点。
实例代码
////编写使用复杂筛选的查询 XElement root = XElement.Load("PurchaseOrders.xml"); IEnumerable<XElement> purchaseOrders = from el in root.Elements("PurchaseOrder") where (from add in el.Elements("Address") where (string)add.Attribute("Type") == "Shipping" && (string)add.Element("State") == "NY" select add) .Any() select el; foreach (XElement el in purchaseOrders) Console.WriteLine((string)el.Attribute("PurchaseOrderNumber"));
// //筛选可选元素 XElement root = XElement.Parse(@"<Root> <Child1> <Text>Child One Text</Text> <Type Value=""Yes""/> </Child1> <Child2> <Text>Child Two Text</Text> <Type Value=""Yes""/> </Child2> <Child3> <Text>Child Three Text</Text> <Type Value=""No""/> </Child3> <Child4> <Text>Child Four Text</Text> <Type Value=""Yes""/> </Child4> <Child5> <Text>Child Five Text</Text> </Child5> </Root>"); var cList = from typeElement in root.Elements().Elements("Type") where (string)typeElement.Attribute("Value") == "Yes" select (string)typeElement.Parent.Element("Text"); foreach (string str in cList) Console.WriteLine(str);
//对元素进行排序 XElement root = XElement.Load("Data.xml"); IEnumerable<decimal> prices = from el in root.Elements("Data") let price = (decimal)el.Element("Price") orderby price select price; foreach (decimal el in prices) Console.WriteLine(el);
////对多个键上的元素进行排序 XElement co = XElement.Load("CustomersOrders.xml"); var sortedElements = from c in co.Element("Orders").Elements("Order") orderby (string)c.Element("ShipInfo").Element("ShipPostalCode"), (DateTime)c.Element("OrderDate") select new { CustomerID = (string)c.Element("CustomerID"), EmployeeID = (string)c.Element("EmployeeID"), ShipPostalCode = (string)c.Element("ShipInfo").Element("ShipPostalCode"), OrderDate = (DateTime)c.Element("OrderDate") }; foreach (var r in sortedElements) Console.WriteLine("CustomerID:{0} EmployeeID:{1} ShipPostalCode:{2} OrderDate:{3:d}", r.CustomerID, r.EmployeeID, r.ShipPostalCode, r.OrderDate);
////计算中间值 XElement root = XElement.Load("Data.xml"); IEnumerable<decimal> extensions = from el in root.Elements("Data") let extension = (decimal)el.Element("Quantity") * (decimal)el.Element("Price") where extension >= 25 orderby extension select extension; foreach (decimal ex in extensions) Console.WriteLine(ex);
//编写基于上下文查找元素的查询 XElement doc = XElement.Parse(@"<Root> <p id=""1""/> <ul>abc</ul> <Child> <p id=""2""/> <notul/> <p id=""3""/> <ul>def</ul> <p id=""4""/> </Child> <Child> <p id=""5""/> <notul/> <p id=""6""/> <ul>abc</ul> <p id=""7""/> </Child> </Root>"); IEnumerable<XElement> items = from e in doc.Descendants("p") let z = e.ElementsAfterSelf().FirstOrDefault() where z != null && z.Name.LocalName == "ul" select e; foreach (XElement e in items) Console.WriteLine("id = {0}", (string)e.Attribute("id"));
////通过 LINQ to XML 使用字典 Dictionary<string, string> dict = new Dictionary<string, string>(); dict.Add("Child1", "Value1"); dict.Add("Child2", "Value2"); dict.Add("Child3", "Value3"); dict.Add("Child4", "Value4"); XElement root = new XElement("Root", from keyValue in dict select new XElement(keyValue.Key, keyValue.Value) );
XElement root = XElement.Load("Data.xml"); Dictionary<string, string> dict = new Dictionary<string, string>(); foreach (XElement el in root.Elements()) dict.Add(el.Name.LocalName, el.Value); foreach (string str in dict.Keys) Console.WriteLine("{0}:{1}", str, dict[str]); Console.WriteLine(root);
/////检索元素的值 XElement e = new XElement("StringElement", "abcd"); Console.WriteLine(e); Console.WriteLine("Value of e:" + (string)e); Console.WriteLine("Value of e by Value:" + e.Value);
//检索元素集合 XElement po = XElement.Load("PurchaseOrder.xml"); IEnumerable<XElement> childElements = from el in po.Elements() select el; foreach (XElement el in childElements) Console.WriteLine("Name: " + el.Name);
////根据元素的名称进行筛选 XElement po = XElement.Load("PurchaseOrder.xml"); IEnumerable<XElement> items = from el in po.Descendants("ProductName") select el; foreach (XElement proName in items) Console.Write("PrdName" + ":" + (string)proName);
////根据元素的名称进行筛选(有命名空间) XNamespace aw = "http://www.adventure-works.com"; XElement po = XElement.Load("PurchaseOrderInNamespace.xml"); IEnumerable<XElement> items = from el in po.Descendants(aw + "ProductName") select el; foreach (XElement prdName in items) Console.WriteLine(prdName.Name + ":" + (string)prdName);
////链接轴方法,有时,当可能存在或不存在间隔上级时,您希望在特定的元素深度,检索所有的元素 XElement root = XElement.Load("Irregular.xml"); IEnumerable<XElement> configParameters =root.Elements("Customer").Elements("Config"). Elements("ConfigParameter"); foreach (XElement cp in configParameters) Console.WriteLine(cp.Value);
////检索单个子元素 XElement po = XElement.Load("PurchaseOrder.xml"); XElement e = po.Element("DeliveryNotes"); Console.WriteLine(e);
////检索属性type的值 XElement val = new XElement("Value", new XAttribute("ID", "1243"), new XAttribute("Type", "int"), new XAttribute("ConvertableTo", "double"), "100"); IEnumerable<XAttribute> xa = from att in val.Attributes() select att; foreach (XAttribute a in xa) if (a.Name.ToString() == "Type") Console.WriteLine(a.Value);
XElement cust = new XElement("PhoneNumbers", new XElement("Phone", new XAttribute("type", "home"), "555-555-5555"), new XElement("Phone", new XAttribute("type", "work"), "555-555-6666") ); IEnumerable<XElement> elList = from el in cust.Descendants("Phone") select el; foreach (XElement el in elList) Console.WriteLine((string)el.Attribute("type"));
////查找具有特定属性的元素 XElement root = XElement.Load("PurchaseOrder.xml"); IEnumerable<XElement> address = from el in root.Elements("Address") where (string)el.Attribute("Type") == "Billing" select el; foreach (XElement el in address) Console.WriteLine(el);
////查找具有特定子元素的元素 XElement root = XElement.Load("TestConfig.xml"); IEnumerable<XElement> tests = from el in root.Elements("Test") where (string)el.Element("CommandLine") == "Examp2.EXE" select el; foreach (XElement el in tests) Console.WriteLine((string)el.Attribute("TestId"));