简体   繁体   中英

Linq XML query the descendants of parent with a specific value in attribute

I need some help with some LINQ to XML. I've the below XML;

<GcctTestData>
  <TestDriveRequest Record="1">
    <element name="Time Zone">(GMT+05:30)</element>
    <element name="Requested Dealer">Concorde</element>
    <element name="Model Year">1999</element>
    <element name="Make">Tata</element>
    <element name="Model/Vehicle Line">Indica</element>
  </TestDriveRequest>
  <TestDriveRequest Record="2">
    <element name="Time Zone">(GMT+05:30)</element>
    <element name="Requested Dealer">Kun"</element>
    <element name="Model Year">2020"</element>
    <element name="Make">BMW"</element>
    <element name="Model/Vehicle Line">3-series</element>
  </TestDriveRequest>
  <TestDriveRequest Record="3">
    <element name="Time Zone">(GMT+05:30)</element>
    <element name="Requested Dealer">KUN Hyundai</element>
    <element name="Model Year">2001</element>
    <element name="Make">Hyundai</element>
    <element name="Model/Vehicle Line">Verna</element>
  </TestDriveRequest>
</GcctTestData>

I tried it like below:

IEnumerable<XElement> xElements =
                from element in root.Elements("TestDriveRequest")
                where element.Attribute("Record").Value == "1"
                select element;

            foreach (XElement el in xElements.Descendants().Where(p => !p.HasElements))
            {
                int keyInt = 0;
                string keyName = el.Attribute("name").Value;

                while (keyValuePairs.ContainsKey(keyName))
                {
                    keyName = $"{el.Attribute("name").Value}_{keyInt++}";
                }
                keyValuePairs.Add(keyName, el.Value);
            }                

I'll have to get the element name attribute value of the element for that parent which have the record value 1

but the linq query is not fetching it...

After implementing the suggestion of @anu-viswan I face the below problem在此处输入图片说明

You need to use root.Descendants instead of root.Elements .

For example,

IEnumerable<XElement> xElements =   from element in root.Descendants("TestDriveRequest")
                where element.Attribute("Record").Value == "1"
                select element;

XContainer.Elements

Returns a filtered collection of the child elements of this element or document, in document order. Only elements that have a matching XName are included in the collection.

XContainer.Descendants

Returns a filtered collection of the descendant elements for this document or element, in document order. Only elements that have a matching XName are included in the collection Output

Complete Code

IEnumerable<XElement> xElements =   from element in root.Descendants("TestDriveRequest")
            where element.Attribute("Record").Value == "1"
            select element;

foreach (XElement el in xElements.Descendants().Where(p => !p.HasElements))
{
   int keyInt = 0;
   string keyName = el.Attribute("name").Value;

   while (keyValuePairs.ContainsKey(keyName))
   {
     keyName = $"{el.Attribute("name").Value}_{keyInt++}";
   }
   keyValuePairs.Add(keyName, el.Value);
}  

Sample Output

在此处输入图片说明

This is how I would create the dictionary :

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace AscendingSequences
{
    class AscendingSequences
    {
        const string FILENAME = @"c:\temp\test.xml";
        public static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<int, Dictionary<string, string>> dict = doc.Descendants("TestDriveRequest")
                .GroupBy(x => (int)x.Attribute("Record"), y => y.Elements("element")
                    .GroupBy(a => (string)a.Attribute("name"), b => (string)b)
                    .ToDictionary(a => a.Key, b => b.FirstOrDefault()))
                    .ToDictionary(x => x.Key, y => y.FirstOrDefault());
        }
    }
}

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