【问题标题】:Parsing XML with key value pair in C# using linq使用 linq 在 C# 中使用键值对解析 XML
【发布时间】:2013-09-19 18:38:21
【问题描述】:

我有以下 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>

我正在尝试将其变成产品列表

产品在哪里

public class Product
{
    public string Id {get;set;}
    public int Point {get;set;}
}

我尝试过这样使用 Linq

XDocument fooXML = XDocument.Load(@"c:\fred\foo.xml");

然后是这个

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

但我得到了一个包含 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 

当我想要一个这样的 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 

我知道我可以通过使用 2 个循环并手动构建列表来作弊,但我更愿意学习如何正确地做到这一点。

谢谢

【问题讨论】:

    标签: c# xml parsing


    【解决方案1】:

    您应该先查询Product 元素,然后分别为每个元素获取fields:

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

    【讨论】:

      【解决方案2】:

      如果您想更进一步,确保您选择的每个产品都有一个 Id 字段和一个点字段,并且该点将解析为一个 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 };
      

      【讨论】:

        猜你喜欢
        • 2013-01-06
        • 1970-01-01
        • 1970-01-01
        • 2016-08-23
        • 2021-08-16
        • 1970-01-01
        • 2019-12-28
        • 1970-01-01
        • 2011-06-13
        相关资源
        最近更新 更多