使用linq在C#中使用键值对解析XML

Ser*_*Now 1 c# xml parsing

我有以下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>
Run Code Online (Sandbox Code Playgroud)

我想把它变成一个产品清单

产品在哪里

public class Product
{
    public string Id {get;set;}
    public int Point {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我尝试过这样使用Linq

XDocument fooXML = XDocument.Load(@"c:\fred\foo.xml");
Run Code Online (Sandbox Code Playgroud)

然后这个

var pairs = XDocument.Parse(fooXML.ToString())
                .Descendants("field")
                .Select (xd => new {Key = xd.Attribute("name").Value,
                                    Value = xd.Attribute("value").Value}).ToList();
Run Code Online (Sandbox Code Playgroud)

但我得到了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 
Run Code Online (Sandbox Code Playgroud)

当我想要这样的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 
Run Code Online (Sandbox Code Playgroud)

我知道我可能通过使用2个循环并手动构建列表来欺骗我的方式,但我更愿意学习如何正确地完成它.

谢谢

Mar*_*zek 5

您应Product首先查询元素,然后field分别为每个元素获取s:

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();
Run Code Online (Sandbox Code Playgroud)