C# LINQ to XML help

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
I'm learning LINQ to XML and am trying some examples to get the hang of it.
I have an XML file that needs to be read and used to populate some Windows form fields including a Listbox. I wondered what the easiest way to approach this would be, I'd prefer not to use loops if possible.

The XML file looks like this:

Code:
<Jobs>
   <Job Name="Job1" SrvName="MyServer" AuthType="SQL" Login="user" Pass="pass">
	<DB1 name="DB1_Name" />
	<DB2 name="DB2_Name" />
	<Table1 IDField="IDFieldName">
		<Field name="F1_Name"/>
		<Field name="F2_Name"/>
		<Field name="F3_Name"/>
	</Table1>
	<Table2 IDField="IDFieldName">
		<Field name="F1_Name"/>
		<Field name="F2_Name"/>
		<Field name="F3_Name"/>
	</Table2>
   </Job>
   <Job Name="Job2" SrvName="MyServer2" AuthType="SQL" Login="user2" Pass="pass2">
	<DB1 name="DB1_Name" />
	<DB2 name="DB2_Name" />
	<Table1 IDField="IDFieldName">
		<Field name="F1_Name"/>
		<Field name="F2_Name"/>
		<Field name="F3_Name"/>
		<Field name="F4_Name"/>
		<Field name="F5_Name"/>
	</Table1>
	<Table2 IDField="IDFieldName">
		<Field name="F1_Name"/>
		<Field name="F2_Name"/>
		<Field name="F3_Name"/>
		<Field name="F4_Name"/>
		<Field name="F5_Name"/>
	</Table2>
   </Job>
</Jobs>

The <Job> and <Field> elements are a dynamic list and are numbers are not predictable. There will always only be 2 <TableX> elements per <Job>.

On the windows form there is a combo box cbmJob that they user selects a job name from (populated at form open from the <Job> elements).
On update of the combo box, textbox fields for SrvName, AuthType, Login and Pass are populated according to the selected job's properties.
Text box fields for <Table1> and <Table2> as well as text boxes for IDFieldName properties for both are populated according to the selected job,
lastly, two seperate Listbox components are populated with the dynamic <Field> lists for the job's <Table1> and <Table2> elements.

How would I efficiently populate the text fields and Listboxes from the appropriate selected Job in the combo box? If possible, help with constructors and main code would be greatly appreciated! I've done plenty of googling and come up with various code snippets but never been able to implement them properly.
 
Last edited:

Thor

Honorary Master
Joined
Jun 5, 2014
Messages
44,236
If it was me and if it was in PHP I would have done something like this:

PHP:
<?php
$XML->load('http://your-xml-source/');
	$feed = array();
	foreach ($XML->getElementsByTagName('item') as $node) {
		$item = array ( 
			'Field_Lorim' => $node->getElementsByTagName('Some_Field_Name')->item(0)->nodeValue,
			'Field_Ipsum' => $node->getElementsByTagName('Another_Field_Name')->item(0)->nodeValue,
			'Field_Bacon' => $node->getElementsByTagName('More_Field_Name')->item(0)->nodeValue,
			'Field_Cheese' => $node->getElementsByTagName('Last_Field_Name')->item(0)->nodeValue,
			);
		array_push($feed, $item);
	}

?>

and then in the HTML I would do a little for loop and simply echo the fields into the areas that has to be populated.
 

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
If it was me and if it was in PHP I would have done something like this:

PHP:
<?php
$XML->load('http://your-xml-source/');
	$feed = array();
	foreach ($XML->getElementsByTagName('item') as $node) {
		$item = array ( 
			'Field_Lorim' => $node->getElementsByTagName('Some_Field_Name')->item(0)->nodeValue,
			'Field_Ipsum' => $node->getElementsByTagName('Another_Field_Name')->item(0)->nodeValue,
			'Field_Bacon' => $node->getElementsByTagName('More_Field_Name')->item(0)->nodeValue,
			'Field_Cheese' => $node->getElementsByTagName('Last_Field_Name')->item(0)->nodeValue,
			);
		array_push($feed, $item);
	}

?>

and then in the HTML I would do a little for loop and simply echo the fields into the areas that has to be populated.

Yeah, I may resort to loops, but trying to avoid them for efficiency - great when it's small but could get rather cumbersome. Unfortunately it's C# winforms too :)
 

FarligOpptreden

Executive Member
Joined
Mar 5, 2007
Messages
5,396
Have you considered deserializing it to a list of Job objects matching a class structure loosely based on your XML schema?
 

FarligOpptreden

Executive Member
Joined
Mar 5, 2007
Messages
5,396
That's a pretty good idea... I'll xsd it and see how that goes...
You don't need to. Having a schema validating your XML documents would be great, but it's not necessary. Just decorate your properties in the classes with XmlAttribute, XmlElement, XmlArray, etc depending on the structure of the document.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Create a backing class for Job, example:
Code:
public class Job
{
   public String Name;
   public String SrvName;
   public String AuthType;
   public String Login;
   public String Pass;
}

Then extract the xml into a collection of this class.
Code:
XDocument xdoc = XDocument.Load("filepath.xml");
List<Job> jobs = (from job in xdoc.Descendants("Job") select new Job { 
  Name = job.Attribute("Name").Value,
  SrvName = job.Attribute("SrvName").Value,
  AuthType = job.Attribute("AuthType").Value,
  Login = job.Attribute("Login").Value,
  Pass = job.Attribute("Pass").Value
}).ToList();

Finally, either iterate through the elements (below example), or link it up directly with your UI elements.
Code:
foreach (Job job in jobs)
{
   Console.WriteLine(job.Name + " " + job.SrvName + " " + job.AuthType + " " + job.Login + " " + job.Pass);
}
 

Hamster

Resident Rodent
Joined
Aug 22, 2006
Messages
42,928
I'm gonna start keeping score of how many times posters come in and repost exactly what hat a previous guy said.

You sir are at 2 this week alone.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
I'm gonna start keeping score of how many times posters come in and repost exactly what hat a previous guy said.

You sir are at 2 this week alone.
Did someone steal your teddy bear?:whistling::D
 

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
[)roi(];18087568 said:
Create a backing class for Job, example:
Code:
public class Job
{
   public String Name;
   public String SrvName;
   public String AuthType;
   public String Login;
   public String Pass;
}

Then extract the xml into a collection of this class.
Code:
XDocument xdoc = XDocument.Load("filepath.xml");
List<Job> jobs = (from job in xdoc.Descendants("Job") select new Job { 
  Name = job.Attribute("Name").Value,
  SrvName = job.Attribute("SrvName").Value,
  AuthType = job.Attribute("AuthType").Value,
  Login = job.Attribute("Login").Value,
  Pass = job.Attribute("Pass").Value
}).ToList();

Finally, either iterate through the elements (below example), or link it up directly with your UI elements.
Code:
foreach (Job job in jobs)
{
   Console.WriteLine(job.Name + " " + job.SrvName + " " + job.AuthType + " " + job.Login + " " + job.Pass);
}

Thanks - examples are always very helpful and welcome!

Hmm... It's only finding one instance of Job in the file - there are definitely 2 as per the example. It's also not finding the attributes for some reason...
*EDIT* never mind, awesome example is awesone, thanks droid! I had an issue with duplicate data files for some reason.


For some other reason I can't fathom, it's not seeing my System.Xml.Linq reference - I had to be explicit about the full reference to XDocument...
System.Xml.Linq.XDocument
 
Last edited:

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Thanks - examples are always very helpful and welcome!

Hmm... It's only finding one instance of Job in the file - there are definitely 2 as per the example. It's also not finding the attributes for some reason...
*EDIT* never mind, awesome example is awesone, thanks droid! I had an issue with duplicate data files for some reason.


For some other reason I can't fathom, it's not seeing my System.Xml.Linq reference - I had to be explicit about the full reference to XDocument...
System.Xml.Linq.XDocument
Happy to help.

As comparison I have the following includes:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

If you still experiencing issue, just check that you have the relevant references loaded.
Screen Shot 2016-08-03 at 9.02.34 PM.png
 

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
[)roi(];18087856 said:
Happy to help.

As comparison I have the following includes:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

If you still experiencing issue, just check that you have the relevant references loaded.
View attachment 379668

Will check and post in the morning, ta muchly - it's helpful posts like this that make MyBB what it is.
Cheers!
 

DominionZA

Executive Member
Joined
May 5, 2005
Messages
8,309
Have you considered deserializing it to a list of Job objects matching a class structure loosely based on your XML schema?
This!
My daily work involves deserializing XML and doing all sorts with the results. It's the least complicated way forward.
 

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
This!
My daily work involves deserializing XML and doing all sorts with the results. It's the least complicated way forward.
As with most aspects of coding; it's down to personal preference / opinion.
 

Willie Trombone

Honorary Master
Joined
Jul 18, 2008
Messages
60,038
This!
My daily work involves deserializing XML and doing all sorts with the results. It's the least complicated way forward.

Indeed, I've learned something valuable!

[)roi(];18088524 said:
As with most aspects of coding; it's down to personal preference / opinion.

100% - and I'm glad I learned about deserializing XML. Seems way more logical and simple than just working with LINQ queries alone. Workign with XML just went from daunting to not too bad in one easy step :)
 
Last edited:

Thor

Honorary Master
Joined
Jun 5, 2014
Messages
44,236
Can someone explain to me how deserializing works with an example in php?

I also want to learn.
 

DominionZA

Executive Member
Joined
May 5, 2005
Messages
8,309
Indeed, I've learned something valuable!



100% - and I'm glad I learned about deserializing XML. Seems way more logical and simple than just working with LINQ queries alone. Workign with XML just went from daunting to not too bad in one easy step :)

Take note that once you have designed/decorated your classes to deserialize properly, you can serialize back to XML with almost zero extra effort.
 
Top