[英]Parsing XML with key value pair in C# using linq
I have the following XML 我有以下XML
<?xml version="1.0"?>
<NavResponse>
<Response>
<Products>
<Product>
<field name="Id" value="BST-U3009W"/>
<field name="Point" value="1"/>
</Product>
<Product>
<field name="Id" value="BST-U5047W"/>
<field name="Point" value="1"/>
</Product>
<Product>
<field name="Id" value="BST-U7023W"/>
<field name="Point" value="1"/>
</Product>
<Product>
<field name="Id" value="BST-U9007"/>
<field name="Point" value="1"/>
</Product>
<Product>
<field name="Id" value="BTS-U8010"/>
<field name="Point" value="1"/>
</Product>
</Products>
</Response>
<Id>00000000-0000-0000-0000-000000000000</Id>
<Errors/>
</NavResponse>
I am trying to turn it into a list of product 我正在尝试将其变成产品列表
where product is 产品在哪里
public class Product
{
public string Id {get;set;}
public int Point {get;set;}
}
I tried using Linq this way 我尝试以这种方式使用Linq
XDocument fooXML = XDocument.Load(@"c:\fred\foo.xml");
and then this 然后这个
var pairs = XDocument.Parse(fooXML.ToString())
.Descendants("field")
.Select (xd => new {Key = xd.Attribute("name").Value,
Value = xd.Attribute("value").Value}).ToList();
but I get this a list of 10 records. 但我得到了10条记录的清单。
Id BST-U3009W
Point 1
Id BST-U5047W
Point 1
Id BST-U7023W
Point 1
Id BST-U9007
Point 1
Id BTS-U8010
Point 1
When I want a list of 5 records like this 当我想要这样的5条记录的列表时
Id = BST-U3009W , Point = 1
Id = BST-U5047W , Point = 1
Id = BST-U7023W, Point = 1
Id = BST-U9007, Point = 1
Id = BTS-U8010, Point = 1
I know I could probably cheat my way by using 2 loops and building the list manually, but that I would much rather learn how to do it properly. 我知道我可以通过使用2个循环并手动构建列表来欺骗自己的方式,但是我宁愿学习如何正确地进行操作。
Thanks 谢谢
You should query for Product
elements first and then get field
s for every one separately: 您应该首先查询Product
元素,然后分别获取每个元素的field
:
var query = from p in xDoc.Root.Element("Response")
.Element("Products")
.Elements("Product")
let id = p.Elements("field")
.First(x => (string)x.Attribute("name") == "Id")
let point = p.Elements("field")
.First(x => (string)x.Attribute("name") == "Point")
select new Product {
Id = (string)id.Attribute("value"),
Point = (int)point.Attribute("value")
};
var items = query.ToList();
If you wanted to go one step further and make sure that each product you select has both an Id field and a point field and also that the point will parse to an int - you could do something like this. 如果您想更进一步,并确保所选的每个产品都具有ID字段和Point字段,并且该Point可以解析为一个int,则可以执行以下操作。
XDocument xml = XDocument.Load(@"c:\fred\foo.xml");
int i = default(int);
var pairs = from product in xml.Descendants("Product")
let id = product.Elements("field").FirstOrDefault(f => f.Attribute("name") != null && f.Attribute("value") != null && f.Attribute("name").Value == "Id")
let point = product.Elements("field").FirstOrDefault(f => f.Attribute("name") != null && f.Attribute("value") != null && f.Attribute("name").Value == "Point" && int.TryParse(f.Attribute("value").Value, out i))
where id != null && point != null
select new Product { Id = id.Attribute("value").Value, Point = i };
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.