Parsing XML using LINQ

Hello,

this is my XML file:

<?xml version="1.0" encoding="utf-8"?>
<start>
	<Current="5">
		<Locations>
			<Location id="1" x="78492.61" y="-80973.03" z="-4403.297"/>
			<Location id="2" x="78323.57" y="-81994.98" z="-4385.707"/>
			<Location id="3" x="78250.57" y="-81994.98" z="-4385.707"/>
		</Locations>
		<Vendor id = "1" x="123456" y="456789" z="0234324"/>
		<Banker id = "1" x="23432" y="3243243" z="5154445"/>
		<Relocate>
			<Relocation id = "1" GpsID="1122" x="324324" y="23432" z="23432432"/>
			<Relocation id = "2" GpsID="4444" x="324324" y="23432" z="23432432"/>			
			<Relocation id = "3" GpsID="2222" x="324324" y="23432" z="23432432"/>
		</Relocate>
	</Current>
</start>

Open in new window


Below are my classes:

	public class Profile //class for storing Locations and [Current] value
    {
		public int Current { get; set; }
        public int Id { get; set; }
        public Single x { get; set; }
        public Single y { get; set; }
        public Single z { get; set; }
    }
	
public class Vendor
	{
		public int Current { get; set; }
		public int VendorID { get; set; }
		public Single VendorX { get; set; }
		public Single VendorY { get; set; }
		public Single VendorZ { get; set; }
	}
	
	public class Banker
	{
		public int Current { get; set; }
		public int BankerID { get; set; }
		public Single BankerX { get; set; }
		public Single BankerY { get; set; }
		public Single BankerZ { get; set; }
	}
	
	public class Relocate
	{
		public int Current { get; set; }
		public int RelocateID { get; set; }
		public int GpsID { get; set; }
		public int RelocateX { get; set; }
		public int RelocateY { get; set; }
		public int RelocateZ { get; set; }
	}
	

Open in new window


Since i am not skilled in parsing XMLs i am not 100% sure classes i made would work with given XMl (as far as i know Each XML node/section acts like a table).

I would want to populate classes with XML data for later processing using LINQ.

If anyone would show me some code it would be great!

Thank you!
andy gehoxAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Fernando SotoRetiredCommented:
Hi Andy;

The below Linq to XML query will parse the XML into classes. I needed to modify two classes and add two classes to do what you needed.

using System.Xml;
using System.Xml.Linq;

XDocument xdoc = XDocument.Load("C:/working directory/start.xml");

// The result variable will contain one element for each Current node with all its elements parsed into classes. 
var result = (from n in xdoc.Descendants("Current")
              select new {
                  Profile = new Profile() {
                                 Current = int.Parse(n.Attribute("Current").Value),
                                 Location = (from l in n.Element("Locations").Elements("Location")
                                             select new Location() {
                                                 id = int.Parse(l.Attribute("id").Value),
                                                 x = Single.Parse(l.Attribute("x").Value),
                                                 y = Single.Parse(l.Attribute("y").Value),
                                                 z = Single.Parse(l.Attribute("z").Value)
                                             }).ToList()
                             },
                  Vendor = new Vendor() {
                               Current = int.Parse(n.Attribute("Current").Value),
                               VendorID = int.Parse(n.Element("Vendor").Attribute("id").Value),
                               VendorX = Single.Parse(n.Element("Vendor").Attribute("x").Value),
                               VendorY = Single.Parse(n.Element("Vendor").Attribute("y").Value),
                               VendorZ = Single.Parse(n.Element("Vendor").Attribute("z").Value)
                           },
                  Banker = new Banker() {
                               Current = int.Parse(n.Attribute("Current").Value),
                               BankerID = int.Parse(n.Element("Banker").Attribute("id").Value),
                               BankerX = Single.Parse(n.Element("Banker").Attribute("x").Value),
                               BankerY = Single.Parse(n.Element("Banker").Attribute("y").Value),
                               BankerZ = Single.Parse(n.Element("Banker").Attribute("z").Value)
                           },
                  Relocate = new Relocate() {
                                 Current = int.Parse(n.Attribute("Current").Value),
                                 RInfo = (from r in n.Element("Relocate").Elements("Relocation")
                                             select new RelocateInfo() {
                                                 RelocateID = int.Parse(r.Attribute("id").Value),
                                                 GpsID = int.Parse(r.Attribute("GpsID").Value),
                                                 RelocateX = int.Parse(r.Attribute("x").Value),
                                                 RelocateY = int.Parse(r.Attribute("y").Value),
                                                 RelocateZ = int.Parse(r.Attribute("z").Value)
                                             }).ToList()
                             }                               
             }).ToList();
             

Open in new window

public class Profile //class for storing Locations and [Current] value
{
    private List<Location> location = new List<Location>();
    public int Current { get; set; }
    public List<Location> Location { get; set; }
}

public class Location
{
    public int id { get; set; }
    public Single x { get; set; }
    public Single y { get; set; }
    public Single z { get; set; }
}

public class Vendor
{
	public int Current { get; set; }
	public int VendorID { get; set; }
	public Single VendorX { get; set; }
	public Single VendorY { get; set; }
	public Single VendorZ { get; set; }
}

public class Banker
{
	public int Current { get; set; }
	public int BankerID { get; set; }
	public Single BankerX { get; set; }
	public Single BankerY { get; set; }
	public Single BankerZ { get; set; }
}

public class Relocate
{
    private List<RelocateInfo> relocateInfo = new List<RelocateInfo>();
    public int Current { get; set; }
    public List<RelocateInfo> RInfo { get; set; }
}
  
public class RelocateInfo
{
    public int RelocateID { get; set; }
    public int GpsID { get; set; }
    public int RelocateX { get; set; }
    public int RelocateY { get; set; }
    public int RelocateZ { get; set; }    
}

Open in new window


The variable result contains 1 anonymous object for each Current node in the XML with children. That anonymous object four object as shown below.

The Anonymous object with its 4 objects.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
andy gehoxAuthor Commented:
Hello Fernando Soto,

Thank you for this awesome solution. I am still a bit puzzled how to access values within the list/classes.

What i need to do is take List with Stored Location under Current ID and process it within my methods and as well other data as vendors / bankers and relocations.

Could you be so kind and provide me with an example how to do that as well?

Much appreciated!

Kind regards.

Andy
Fernando SotoRetiredCommented:
Hi Andy;

In the solution I provided the variable result which will contain a collection of the parsed XML. Each element of the collection in the result variable will contain all the info from one XML node and all its children with the tag Current. Therefore if there were more then one node Current then the collection of result would contain one for each. The following is how you can iterate the collection and pick out the values.

// Iterate through all the Current node information
foreach (var current in result)
{
    // Get the attribute Current data
    Console.WriteLine("Current = {0}", current.Profile.Current);
    // Get the Profile info
    foreach (Location loc in current.Profile.Location)
    {
        Console.WriteLine("\tLocation Info : \n\tID = {0}\tX = {1}\tY = {2}\tZ = {3}",
            loc.id, loc.x, loc.y, loc.z);
    }
    // Get the Vendor info
    Console.WriteLine("\n\tVendor Info  :   ID = {0}\tX = {1}\tY = {2}\tZ = {3}",
        current.Vendor.VendorID, current.Vendor.VendorX, current.Vendor.VendorY, current.Vendor.VendorZ);
    // Get Banker Info
    Console.WriteLine("\n\tBanker Info  :   ID = {0}\tX = {1}\tY = {2}\tZ = {3}",
        current.Banker.BankerID, current.Banker.BankerX, current.Banker.BankerY, current.Banker.BankerZ);
    // Get Relocate Info
    foreach (RelocateInfo relo in current.Relocate.RInfo)
    {
        Console.WriteLine("\tRelocate Info : \n\tID = {0}\tGps = {1}X = {2}\tY = {3}\tZ = {4}",
            relo.RelocateID, relo.GpsID, relo.RelocateX, relo.RelocateY, relo.RelocateZ);
    }
}

Open in new window

andy gehoxAuthor Commented:
Really nice and helpful as always!
Fernando SotoRetiredCommented:
Thanks, glad to of helped.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.