首页 > 解决方案 > 获取按子级子节点过滤的父节点,XML

问题描述

我有以下 XMLdataset

<?xml version="1.0" ?>
<productCatalog>
  <catalogName>Freeman and Freeman Unique Catalog 2010</catalogName>
  <expiryDate>2012-01-01</expiryDate>

  <products>
    <product id="1001">
      <productName>Gourmet Coffee</productName>
      <description>The finest beans from rare Chillean plantations.</description>
      <productPrice>0.99</productPrice>
      <inStock>true</inStock>
      <category id ="100">
        <name>Latin Breakfast</name>
        <description>International Range</description>
        <subcategory id ="SUB1000">
          <name>Energy</name>
          <description>blah blah</description>
        </subcategory>
      </category>
    </product>
    <product id="1002">
      <productName>Blue China Tea Pot</productName>
      <description>A trendy update for tea drinkers.</description>
      <productPrice>102.99</productPrice>
      <inStock>true</inStock>
      <category id ="200">
        <name>Asian Breakfast</name>
        <description>Asian Range</description>
        <subcategory id ="SUB1000">
          <name>Organic</name>
          <description>healthy organic food for a longer life</description>
        </subcategory>
      </category>
    </product>
    <product id="1002">
      <productName>Blue China Tea Pot</productName>
      <description>A trendy update for tea drinkers.</description>
      <productPrice>102.99</productPrice>
      <inStock>true</inStock>
      <category id ="300">
        <name>Italian Breakfast</name>
        <description>Roman Breakfast</description>
        <subcategory id ="SUB2000">
          <name>italian</name>
          <description>Roman sttyle breakfast</description>
        </subcategory>
      </category>
    </product>
  </products>
</productCatalog>

我想获取所有子类别 id = "SUB1000" 的产品

我已经写了代码

  public static void ProductsFilteredBySubCategory(string path) {
            XElement root = XElement.Load(path);
           IEnumerable<XElement> productElems =   root.Element("products").Elements().Where(e => e.Name == "product" ).Select(s => s);

            IEnumerable<XElement> subcats;

            foreach (var item in productElems){

                Console.WriteLine( item.Element("category").Elements().Where(e => e.Name == "subcategory").Select(s => s.Name) );
            }
        }

但是中的打印语句foreach似乎没有被过滤的产品,我如何过滤所需的产品subcategory id?也许我以不正确的方式这样做......

标签: c#xmllinq

解决方案


Descendants在这种情况下可能很有用。

var document = XDocument.Load(path);

var products = document.Descendants("product")
    .Where(product => product.Descendants("subcategory")
                             .Any(sub => sub.Attributes("id")
                                              .Any(id => id.Value == "SUB1000")));

foreach(var product in products)
{
    var subId = product.Attributes("id").Select(id => id.Value).FirstOrDefault();

    Console.WriteLine($"Product: {subId}");
}        

推荐阅读