获取通过子级子节点,XML过滤的父节点

时间:2019-09-26 04:30:25

标签: c# xml linq

我有以下XML dataset

<?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中的print语句似乎没有被过滤的产品,如何按所需的subcategory id过滤产品?也许我这样做的方式不正确...

3 个答案:

答案 0 :(得分:0)

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}");
}        

答案 1 :(得分:0)

您正在以某种回旋的方式来处理它。这是我的结构方式:

XDocument document = XDocument.Load(path);

var elements = document.Descendants("subcategory")
                            .Where(i => (string)i.Attribute("id") == "SUB1000")
                            .Select(i => i.Parent.Parent);

foreach(var element in elements)
{
    Console.WriteLine(element);
}

当然,在这里我不是在查看特定的实体类型,而是假设ID对于您要查找的内容是唯一的,它将提取正确的元素。

答案 2 :(得分:0)

您可以使用以下代码获取产品

 var document = XDocument.Load("pathtothexml");
 var coll = document.Descendants("subcategory").Where(s => s.Attribute("id").Value.Equals("SUB1000")).Ancestors("product");