C# 使用 linq 查询 xmlnode

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/576678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:56:39  来源:igfitidea点击:

query xmlnode using linq

c#linqlinq-to-xml

提问by

I have following file:

我有以下文件:

<root>
  <Product desc="Household">
    <Product1 desc="Cheap">
        <Producta desc="Cheap Item 1" category="Cooking" />
        <Productb desc="Cheap Item 2" category="Gardening" />
    </Product1>
    <Product2 desc="Costly">
        <Producta desc="Costly Item 1" category="Decoration"/>
        <Productb desc="Costly Item 2" category="Furnishing" />
        <Productc desc="Costly Item 3" category="Pool" />
    </Product2>
  </Product>
</root>

I want to find out info like: Total items in Cheap and Costly, list of all category (like Cooking, Gardening, DEcoration...), list of sorted category and select only the Product which is 'Costly'

我想找出这样的信息:便宜和昂贵的商品总数、所有类别的列表(如烹饪、园艺、装饰...)、分类类别列表并仅选择“昂贵”的产品

How can i do using LINQ. I did this till now:

我该如何使用 LINQ。我这样做到现在:

 XElement xe = XElement.Load(Server.MapPath("~/product.xml"));
 ????

采纳答案by Jon Skeet

Your XML structure is unfortunate as it uses a Product element for three levels of the hierarchy. Do you have other elements similar to the "household" one?

不幸的是,您的 XML 结构使用 Product 元素作为层次结构的三个级别。你还有其他类似“家”的元素吗?

Assuming we only want the household ones, you can use:

假设我们只想要家庭的,你可以使用:

Count items in each of cheap/costly

计算每个便宜/昂贵的物品

xe.Element("Product") // Select the Product desc="household" element
  .Elements() // Select the elements below it
  .Select(element => new { Name=(string) element.Attribute("desc"),
                           Count=element.Elements().Count() });

List all categories

列出所有类别

xe.Descendants() // Select all descendant elements
  .Attributes() // All attributes from all elements
  // Limit it to "category" elements
  .Where(attr => attr.Name == "category")
  // Select the value
  .Select(attr => attr.Value)
  // Remove duplicates
  .Distinct();

To sort this, just use .OrderBy(x => x)at the end.

要对此进行排序,只需.OrderBy(x => x)在最后使用。

Select 'costly' products

选择“昂贵”的产品

xe.Descendants() // Select all elements
  // Only consider those with a "Costly" description
  .Where(element => (string) element.Attribute("desc") == "Costly")
  // Select the subelements of that element, and flatten the result
  .SelectMany(element => element.Elements());

回答by Marc Gravell

Well, personally I find it easier with XmlDocument:

好吧,我个人觉得使用XmlDocument以下方法更容易:

    XmlDocument root = new XmlDocument();
    root.LoadXml(xml); // or .Load(path);

    var categories = root.SelectNodes(
        "/root/Product/Product/Product/@category")
        .Cast<XmlNode>().Select(cat => cat.InnerText).Distinct();
    var sortedCategories = categories.OrderBy(cat => cat);
    foreach (var category in sortedCategories)
    {
        Console.WriteLine(category);
    }

    var totalItems = root.SelectNodes(
         "/root/Products/Product/Product").Count;
    Console.WriteLine(totalItems);

    foreach (XmlElement prod in root.SelectNodes(
        "/root/Product/Product[@desc='Costly']/Product"))
    {
        Console.WriteLine(prod.GetAttribute("desc"));
    }