如果我们查看来自this link的XML示例
我需要什么样的查询才能获得地址类型为zip = 98112
的{{1}}的元素值PurchaseOrderNumber="99505"
?
我尝试使用Billing
和System.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);
答案 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
。