1

I am trying to learn about LINQ and XML files for data storage, while I teach myself C# and VS2010. I want to read an XML file with a list of server info for some SQL servers that I have in my virtual lab that I use for testing.

My XML file looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<ServerList>
    <Server>
        <Name>SQLSVR1</Name>
        <Type>Windows Server 2008 R2</Type>
        <Product>Microsoft SQL Server 2008</Product>
        <Database>AspNetDB</Database>
        <UID>Admin</UID>
        <PWD>!Passw0rd</PWD>
    </Server>

    <Server>
        <Name>SQLSVR2</Name>
        <Type>Windows Server 2008 R2</Type>
        <Product>Microsoft SQL Server 2008</Product>
        <Database>AspNetDB</Database>
        <UID>Admin</UID>
        <PWD>!Passw0rd</PWD>
    </Server>
</ServerList>

I have a Windows form, which has a ComboBox ("cbSQLServers"). I'd like to populate that ComboBox in the Form_Load() event with the results from the XML file.

    private void Form1_Load(object sender, EventArgs e)
    {
        string filePath = @"..\\..\\ServerList.xml";

        if (File.Exists(filePath))
        {
            XDocument xDoc = XDocument.Load(filePath);

            var data = from item in xDoc.Descendants("server")
                       select new
                       {
                           serverName = item.Element("Name").Value,
                           serverType = item.Element("Type").Value,
                           serverProduct = item.Element("Product").Value
                       };

            foreach (var p in data)
                cbSQLServers.Items.Add(p.ToString());
            // I used the Console to test if it was doing anything.
            // Console.WriteLine(p.ToString());
        }
        else
        {
            MessageBox.Show("The file " + filePath + " does not exist.");
        }
    }

My final goal with this, is that when I run the program and select an item from the ComboBox, it will display the information for that server in a ListBox on the form called LbLog:

    private void cbSQLServers_SelectedIndexChanged(object sender, EventArgs e)
    {
        /*
         * Pseudo-code...not sure how to pass from Form1_Load() to _SelectedIndexChanged.
            lbLog.Items.Add("Server Name: " + cbSQLServers.SelectedIndex);
            lbLog.Items.Add("\t Type: " + cbSQLServers.SelectedIndex);
            lbLog.Items.Add("\t Product: " + cbSQLServers.SelectedIndex);
            lbLog.Items.Add("\t Database: " + cbSQLServers.SelectedIndex);
            lbLog.Items.Add("\t UID: " + cbSQLServers.SelectedIndex);
            lbLog.Items.Add("\t PWD: " + cbSQLServers.SelectedIndex);
        */
    }

Could anyone help me with determining how to read the data from the XML file with LINQ?

5
  • @"..\\..\\ServerList.xml" is wrong; use either @"..\..\ServerList.xml" or "..\\..\\ServerList.xml", not both. Commented Mar 30, 2012 at 17:25
  • Dour, thanks for the catch. I hadn't realized that I had used both...I think I escaped first and then threw @ in later without removing the escapes. Oops! It doesn't affect the output (or lack of it) though ;-( Commented Mar 30, 2012 at 17:29
  • Another bit of advice; do not name identifiers xDoc, data, item, Type and so on; these do not mean anything. C# is a strongly-typed language, it will tell you what each data type is, you do not need to mangle the names. Identifiers should explain their meaning. Commented Mar 30, 2012 at 18:18
  • Please don't prefix your titles with "C#" and such. That's what tags are for. Commented Mar 30, 2012 at 18:43
  • Thanks. First time here, lots of various rules to remember. Commented Mar 30, 2012 at 18:52

2 Answers 2

1

data in your code is an anonymous type, calling ToString() on that is probably not going to give you what you want.

If you want to later use individual fields of cbSQLServers in cbSQLServers_SelectedIndexChanged, you should save the object, not smash it into a string.

Create a class that contains the data in the types you want:

public class MyServer
{
    public string Name { get; private set };
    public string OS { get; private set };
    public string Product { get; private set };

    public MyServer(string name, string os, string product)
    {
        this.Name = name;
        this.OS = os;
        this.Product = product;
    }
}

Then save instances of this type:

cbSQLServers.DisplayMember = "Name";
foreach (var p in data)
    cbSQLServers.Items.Add(new MyServer(p.servername, p.serverType, p.serverProduct));

Then in your handler, you can use individual fields of the selected combobox item:

MyServer selectedServer = cbSQLServers.SelectedItem as MyServer;
DoWhateverWith(selectedServer.OS);
Sign up to request clarification or add additional context in comments.

2 Comments

Dour High Arch, thank you for the example. I guess we were working on it at the same time, because I read your links and was able to create a class to handle the data: ` private class SelectedServer { public string serverName, serverType, serverProduct; public SelectedServer(string name, string type, string product) { serverName = name; serverType = type; serverProduct = product; }`
Well I'll be damned...I'm apparently not intelligent enough to figure out how to reply with code... codetest works but not an actual code block (even with format spaces). Oh well. Thank you for your advice, and the link to the "stringly-typed" article. I'm still learning (none of this is covered in my class that I'm taking...just the basics of programming, form controls, and extremely basic OOP). I appreciate your help and advice!
1

In your XML the element is called "Server", but in your Linq you reference it as "server". The case needs to match since both XML and Linq to XML are case-sensitive.

1 Comment

Mike, Thanks for that! The output panel displayed the Console output after I made that change.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.