现在的位置: 首页 > 综合 > 正文

LINQ to XML 实战

2013年08月02日 ⁄ 综合 ⁄ 共 6409字 ⁄ 字号 评论关闭

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"));

抱歉!评论已关闭.