Hello all,

I have an xml file with the information below:

<?xml version="1.0" encoding="utf-8" ?>
  <ServerNames>
    <Name>dfwnbonner1</Name>
  </ServerNames>

I am trying to get the Name of a server into a listview. This works fine with the above xml but as soon as I add another server name in <Name></Name> it crashes. This is killing me and I have been looking at it for hours. Here is my code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using FX.Network.Utility;


namespace CMC_QA_Env
{
    public partial class ViewServers : Form
    {
        public ViewServers()
        {
            InitializeComponent();
            this.WindowState = FormWindowState.Maximized;
            FillList();
            


         }

    public static  DataTable GetServers()
    {
        DataSet dsStore = new DataSet();
        dsStore.ReadXml("config.xml");
        // Test the count of tables and a relation
        //MessageBox.Show(dsStore.Tables.Count + "  "  +  dsStore.Relations[0].RelationName);
        return dsStore.Tables["ServerNames"];
    }


    private void FillList()
        {
            
            serverList.Items.Clear();
            DataTable dtServers = GetServers();

            serverList.BeginUpdate();
            foreach (DataRow dr in dtServers.Rows)
            {
                ListViewItem listItem = new ListViewItem(dr["Name"].ToString());
                
                string serverStatus = ReturnStatus(dr["Name"].ToString());

                if (serverStatus == "Online")
                {
                    listItem.SubItems.Add(NetworkDiscovery.GetIPAddress(dr["Name"].ToString()));
                }
                else
                    listItem.SubItems.Add("0.0.0.0");

                listItem.SubItems.Add(ReturnStatus(dr["Name"].ToString()));
                

                listItem.ImageIndex = 0;
                serverList.Items.Add(listItem);      
            }

            if (serverList.Columns.Count == 0)
            {
                serverList.Columns.Add("Server Name", 150, HorizontalAlignment.Left);
                serverList.Columns.Add("IP Address", 100, HorizontalAlignment.Left);
                serverList.Columns.Add("Status", 100, HorizontalAlignment.Left);


            }
            serverList.EndUpdate();
        }

Like I said, it displays everything fine with 1 server listed in the XML file but as soon as I add another it crashes at the line: return dsStore.Tables["ServerNames"];

Also if I uncomment

MessageBox.Show(dsStore.Tables.Count + "  "  +  dsStore.Relations[0].RelationName);

It crashe with both 1 and 1+ servernames.

THANKS for anyone that can assist.

Dani AI

Generated

Nice find — wrapping each server in its own element is the correct fix for how DataSet.ReadXml infers tables. DataSet maps the XML structure: a repeating "record" element becomes a DataTable (the element name becomes the table name) and its child elements become columns. A flat list of sibling <Name> elements under the root does not present a record node for ReadXml to treat as rows, so the table the code expected was not created.

That also explains the MessageBox crash: accessing dsStore.Relations[0] assumes at least one relation exists. If the XML does not produce any parent/child tables, the Relations collection is empty and indexing into it throws an exception. Always check collection counts before indexing (Tables.Count, Relations.Count) to avoid that failure.

Quick troubleshooting snippets useful for diagnosing what ReadXml produced:

DataSet ds = new DataSet();
ds.ReadXml("config.xml");
foreach (DataTable t in ds.Tables)
{
    Debug.WriteLine("Table: " + t.TableName);
    foreach (DataColumn c in t.Columns)
        Debug.WriteLine("  Column: " + c.ColumnName);
}

For a simpler, schema-independent approach, extract name values directly with LINQ to XML instead of relying on DataSet table inference:

var names = XDocument.Load("config.xml")
                    .Descendants("Name")
                    .Select(x => (string)x);
foreach (var n in names)
    listView.Items.Add(new ListViewItem(n));

Best practices: supply a repeating record element when intending to use DataSet.ReadXml, or provide an XSD and call ReadXmlSchema first for deterministic mapping. For small config files, LINQ to XML is less brittle and often clearer. ’s change to add per-server nodes is the recommended layout when using DataSet.ReadXml.

Hey guys. I found out my problem. My XML was not in the correct format. Changed to This

<?xml version="1.0" encoding="utf-8" ?>
<ServerNames>
  <server>
    <id>1</id>
    <Name>dfwnbonner1</Name>
  </server>
</ServerNames>

and changed the reference here:

return dsStore.Tables["server"];    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.