C#查询XML文件

时间:2014-01-04 05:59:03

标签: c# xml

如果我们查看来自this link的XML示例 我需要什么样的查询才能获得地址类型为zip = 98112的{​​{1}}的元素值PurchaseOrderNumber="99505"

我尝试使用BillingSystem.Xml.Linq修改Microsoft的示例代码,但我无法做到。

我制作的代码(显然不起作用)是:

System.Xml.XPath

使用此代码时,我得到结果:

XElement root = XElement.Load(@"C:\Projects\XML_Tutorial\PurchaseOrders.xml");

IEnumerable<XElement> po =
        from el in root.Elements("PurchaseOrder")
        where //(string)el.Attribute("PurchaseOrderNumber") == "99503" &&
           (from add in root.Descendants("Address") // either use root.Descendants or el.Elements
            where (string)add.Attribute("Type") == "Billing" &&
                  (string)el.Attribute("PurchaseOrderNumber") == "99505"
            select add)
            .Any()
        select el;

foreach (XElement el in po)
    textBox1.AppendText((string)el.Value + System.Environment.NewLine);

2 个答案:

答案 0 :(得分:2)

您说您需要<zip>元素,但您的查询会返回整个<PurchaseOrder>,因为您返回el

在处理LINQ to XML时,我更喜欢基于方法的查询:

var doc = XDocument.Load("Input.xml");

var zip = doc.Root
             .Elements("PurchaseOrder")
             .FirstOrDefault(o =>
                  (int)o.Attribute("PurchaseOrderNumber") == 99505)
             .Elements("Address")
             .FirstOrDefault(a => (string)a.Attribute("Type") == "Billing")
             .Element("Zip");

var zipValue = (int)zip;

我认为只有一个address type设置为Billing。如果不是这样,您可以稍微修改一下查询:

var zips = doc.Root
              .Elements("PurchaseOrder")
              .FirstOrDefault(o => (int)o.Attribute("PurchaseOrderNumber") == 99505)
              .Elements("Address")
              .Where(a => (string)a.Attribute("Type") == "Billing")
              .Select(a => a.Element("Zip"));

zips将为IEnumerable<XElement>,因此您可以使用foreach将所有内容打印到控制台:

foreach (var zipElement in zips)
    Console.WriteLine((int)zipElement);

答案 1 :(得分:0)

以下是编写同一查询的另外两种方法:

第一种方法:

var zip = xDoc.Descendants("PurchaseOrder")
              .Where(el => el.Attribute("PurchaseOrderNumber")
              .Value == "99505").Descendants("Address")
              .Single(el => el.Attribute("Type").Value == "Billing")
              .Element("Zip");

第二种方法:

var zip = xDoc.Descendants("Address")
              .Single(el => el.Parent.Attribute("PurchaseOrderNumber").Value == "99505" && el.Attribute("Type").Value == "Billing")
              .Element("Zip");

请注意,我假设只存在一个结算地址。另外,您可以使用Single()代替First