简体   繁体   中英

get parent node filtered by sub level child node, XML

I have the following 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>

i want to get all products who's with subcategory id = "SUB1000"

i have written the code

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

but the print statement in the foreach does not seems to have the products that was filtered, How do i filter the products by the desired subcategory id ? Maybe i'm doing this in the incorrect way...

Descendants can be useful in this case.

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

You're going about it in somewhat of a roundabout way. Here is how I would structure this:

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

Granted, here I am not looking at specific entity types, but just assuming that the IDs are unique for what you are trying to find, that will extract the right elements.

You can use the below code to get the product

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM