简体   繁体   中英

return employees using linq to xml

Given the below xml I need to return all the employees that belong to a department. So when DepartmentName=Fashion should return 3 employees

    <?xml version="1.0" encoding="utf-8" ?>
    <Store>
      <Departments>
        <Department name="Fashion">
          <Employees>
            <Employee FirstName="Jo" Surname="Blogg"/>
            <Employee FirstName="Mark" Surname="Smith"/>
            <Employee FirstName="Rose" Surname="Blogg2"/>
          </Employees>
        </Department>    
        <Department name="Makeup">
          <Employees>     
            <Employee FirstName="Sonia" Surname="Smith2"/>
            <Employee FirstName="Jenny" Surname="Blogg3"/>
          </Employees>
        </Department>   
     </Departments>   
    </Store>

what I have tried but does not compile and other tries didnt return the wanted result

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;

    namespace ConsoleApplicationXml
    {
        class Program
        {
            static void Main(string[] args)
            {
                var xDocument = XDocument.Load("Store.xml");

                //Get all employees that belong to "Fashion
                string departmentName = "Fashion";

       //compiles but get object variable not set
        var employees = (from emp in xDocument.Descendants("Employees")
                         where (emp.Parent.FirstAttribute.Value == departmentName)

                         select new Employee
                         {
                             DepartmentName = departmentName,
                             FirstName = emp.FirstAttribute.Value,
                             Surname = emp.LastAttribute.Value
                         }).ToList();

//DOES NOT COMPILE!!

                var employees = (from emp in xDocument.Descendants("Employees")
                                 where (emp.Parent.FirstAttribute.Value == departmentName)
                                 let xFirstName = emp.Element("Employee").FirstAttribute("FirstName")
                                 let xLastName = emp.Element("LastName")
                    select new Employee
                    {
                        DepartmentName = departmentName,
                        FirstName = xFirstName.Value,
                        Surname = xLastName.Value
                    }).ToList();
            }
        }

        public class Employee
        {
            public string DepartmentName { get; set; }
            public string FirstName { get; set; }
            public string Surname { get; set; }
        }
    }

You can use two from clause aka SelectMany() to filter Department elements and select corresponding Employee elements :

var employees = (from department in xDocument.Descendants("Department")
                 from emp in department.Descendants("Employee")
                 where department.Attribute("name").Value == departmentName
                 select new Employee
                 {
                    DepartmentName = departmentName,
                    FirstName = emp.Attribute("FirstName").Value,
                    Surname = emp.Attribute("Surname").Value
                 }).ToList();

In your first example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace ConsoleApplicationXml
{
    class Program
    {
        static void Main(string[] args)
        {
            var xDocument = XDocument.Load("Store.xml");

            //Get all employees that belong to "Fashion
            string departmentName = "Fashion";

   //compiles but get object variable not set
    var employees = (from emp in xDocument.Descendants("Employees")
                     where (emp.Parent.FirstAttribute.Value == departmentName)

                     select new Employee
                     {
                         DepartmentName = departmentName,
                         FirstName = emp.FirstAttribute.Value,
                         Surname = emp.LastAttribute.Value
                     }).ToList();

what you are doing wrong is that the emp variable is for the Employees tag, therefore the FirstAttribute and LastAttribute you are trying to use have no meaning. Use instead this code:

var employeesParent = xDocument.Descendants("Employees").Where(element => element.Parent.Attribute("name").Value == departmentName);
var employees = (from emp in employeesParent.Descendants()
                         select new Employee
                         {
                             DepartmentName = departmentName,
                             FirstName = emp.Attribute("FirstName").Value,
                             Surname = emp.Attribute("Surname").Value
                         }).ToList();

I hope it helps.

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