Thursday, July 19, 2012

C# Load XML using XLINQ (LINQ to XML)


Today I'll show how to load an XML file into objects using XLINQ (Language Integrated Query for XML).
Imaging that you have an XML file which contains an Employee list with corresponding information about each employee. Now you want to load this list into memory and work with that data. For these purposes we have XLINQ technology which allows you to load the data from XML directly into business objects. 
Let's see how to use XLINQ in C#. First, we need to create our business objects:
public class Employee
{
    public int EmployeeID { get; set; }
    public string EmployeeName { get; set; }
    public string EmployeePosition { get; set; }
    public string EmployeeCountry { get; set; }
    public Project[] Projects { get; set; }
}

public class Project
{        
    public string ProjectCode { get; set; }
    public int ProjectBudget { get; set; }
}
So, each employee has an ID, Name, Position he holds, Country he lives. Each employee can participate several projects. The Project object contains a project Code and project Budget. Ok, here how employee object looks like in XML:
<employee>
    <id>1001</id>
    <name>John</name>
    <position>Developer</position>
    <country>USA</country>
    <projects>
        <project>
            <code>Orlando</code>
            <budget>1000</budget>
        </project>
        <project>
            <code>Rocket</code>
            <budget>7000</budget>
        </project>
    </projects>
</employee>
And finally this is how we loading the XML into our objects:
List<Employee> employeeList =
                (
                    from e in XDocument.Load(@"..\..\Employees.xml").Root.Elements("employee")
                    select new Employee
                    {
                        EmployeeID = (int)e.Element("id"),
                        EmployeeName = (string)e.Element("name"),
                        EmployeePosition = (string)e.Element("position"),
                        EmployeeCountry = (string)e.Element("country"),
                        Projects =
                        (
                            from p in e.Elements("projects").Elements("project")
                            select new Project
                            {
                                ProjectCode = (string)p.Element("code"),
                                ProjectBudget = (int)p.Element("budget")
                            }).ToArray()
                    }).ToList();
Download the code for this example (Visual Studio 2010).

8 comments:

  1. Great code -
    it solved 1/2 of my problem.
    Thanks

    Question:
    How do I go about getting ALL the data to display in a dataGrid for example.

    I can access the List or the Array one @ a time, but I need to merge (if you will) data from both XML nodes (parent/child).

    If you could point me the the right direction that would be great.

    Thanks

    ReplyDelete
    Replies
    1. Hi!
      You cannot show XML structure in one datagrid unless your XML has only one level. Think of XML as of set of tables, it's actually similar to DataSet.
      So if, for instance, your XML has 3 levels - show each level in separate datagrid.

      Delete
  2. Hi -
    Thanks for the reply, I was able to solve my issue.
    You are correct, apparently each leave of the XML file is saved to a new table in the dataSet.

    I created another dataSet and used LINQ to join each dataTable within my dataSet containing my XML data and moved that data to my new dataSet.

    I was then able to display my new dataTable/Set to a dataGrid.

    Thanks again

    ReplyDelete
  3. What if the XML structure is the following. (Couldn't write XML in the comment.)

    body
    employees
    employee
    ...

    ReplyDelete
  4. Thanks. Super helpful as suits just what I wanted to do and I am a newbie to Linq

    ReplyDelete
  5. How to view result as string ? and add to listview ?

    ReplyDelete
  6. Thank you very much for sharing.
    Escpecially the Products[] and following ...}).ToArray()
    solved a Problem that kept me busy for quite a Long time.
    Thanks

    ReplyDelete
  7. Thanks so much for sharing this. It simplified the conversion process for a new project I am working on.

    ReplyDelete