Link to home
Start Free TrialLog in
Avatar of Abirami Rajendran
Abirami RajendranFlag for United States of America

asked on

Query XML using Linq

How do I get the employee list from below XML

<?xml version="1.0" encoding="utf-8"?>
<Employee>
  <Some_XML_1 />
  <Some_XML_2 />
  <EmployeeList>
    <id>1</id>
    <name>abc</name>
  </EmployeeList>
  <EmployeeList>
    <id>2</id>
    <name>def</name>
  </EmployeeList>
  <EmployeeList>
    <id>3</id>
    <name>hij</name>
  </EmployeeList>
</Employee>

I need a collection of ID & Name. Is it possible in LINQ or should we go back to DOM
Avatar of BuggyCoder
BuggyCoder
Flag of India image

here is code for linq to xml for the same:-
var strXML =
                "<Employee><EmployeeList><id>1</id><name>abc</name></EmployeeList>" +
                "<EmployeeList><id>2</id><name>def</name></EmployeeList>" +
                "<EmployeeList><id>3</id><name>hij</name></EmployeeList></Employee>";

            var xmlElem = XElement.Parse(strXML);

            var list = xmlElem.Descendants("EmployeeList")
                .Select(e => new
                                 {
                                     ID = e.Descendants("id").First().Value,
                                     Name = e.Descendants("name").First().Value
                                 })
                .ToList();

Open in new window

My version - use LinqPad for easy development:

      XElement data = XElement.Parse(
      @"<Employee>
            <Some_XML_1 />
            <Some_XML_2 />
            <EmployeeList>
                  <id>1</id>
                  <name>abc</name>
            </EmployeeList>
            <EmployeeList>
                  <id>2</id>
                  <name>def</name>
            </EmployeeList>
            <EmployeeList>
                  <id>3</id>
                  <name>hij</name>
            </EmployeeList>
            </Employee>");

      var employees = data.Descendants("EmployeeList");
      
      foreach (var employee in employees)
      {
            var id = employee.Element("id").Value;
            var name = employee.Element("name").Value;
            // Rest of code...
      }

Gary Davis
Avatar of Abirami Rajendran

ASKER

Thanks, But I get the following error for the the below code:

XElement xmlElem = XElement.Parse(strXML);

            var list = xmlElem.Descendants("EmployeeList")
                .Select(e => new
                                 {
                                     ID = e.Descendants("id").First().Value,
                                     Name = e.Descendants("name").First().Value
                                 })
                .ToList();



'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>' could be found (are you missing a using directive or an assembly reference?)
using System.Linq;
using System.Xml.Linq;

Also add reference to System.Xml and System.Xml.Linq from add references in VS
Sorry both the solutions doesnt work. I get the count as 0 for the list  & its not even going inside the foreach loop. But there are records in the XML

Could it be because of xml namespace in the EmployeeList node?
There is no namespace shown in your data example above but if there is one in your actual data, it could have an effect.
OK here it is
<EmployeeList xmlns="http://...">
<id>1</id>
    <name>abc</name>
  </EmployeeList>
SOLUTION
Avatar of BuggyCoder
BuggyCoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
A little better performance within the loop:

      XNamespace ns = "http://a.com";
      XName Id = ns + "id";
      XName Name = ns + "name";      

      var employees = data.Descendants(ns + "EmployeeList");
      employees.Dump("Employees");

      foreach (var employee in employees)
      {
            var id = employee.Element(Id).Value;
            var name = employee.Element(Name).Value;
            // Rest of code...
      }

Details at http://msdn.microsoft.com/en-us/library/cc716786.aspx

BuggyCoder's solution will also work with the appropriate edits.

Gary