0

I am trying to read XML files from different machines, some of these files may have data elements that others don't have. Currently, I am using a Try-Catch block to handle these situations but I was wondering if there was a better way of doing this, any thoughts?

XmlDataDocument xmlDatadoc = new XmlDataDocument();
xmlDatadoc.DataSet.ReadXml("MachineData.xml");

   DataSet ds = new DataSet("AppData");
   ds = xmlDatadoc.DataSet;

   DataView dv = new DataView(ds.Tables[config.GlobalVars.Paths]);
   foreach (DataRowView drv in dv)
   {
      try
      {
         cApp.TransferProtcol = drv["TransferProtocol"].ToString();
      }
      catch { }

      try
      {
         cApp.RemoteServerPath = drv["RemoteServer"].ToString();
      }
      catch { }
   }

Ok, I figured out a solution based upon John Saunders post:

     if(ds.Tables[0].Columns.Contains("TransferProtocol")
     {
          try
          {
             if (drv["TransferProtocol"].ToString().Length > 0)
             {
                 cApp.TransferProtcol = drv["TransferProtocol"].ToString();
             }
          }
          catch(Exception e)
          {
             Messagebox.Show(e.Message);
          }
     }

I agree about the empty Catch blocks but I stubbed them out for testing purposes. I have since edited my post as to what my Try-Catch block looks now.

Mark Kram
  • 5,672
  • 7
  • 51
  • 70

2 Answers2

3

That's a horrible way to "handle" the problem. If the XML may legitimately be missing elements, then check to see if the elements are present before trying to access them.

Your empty catch blocks ignore all exceptions that occur inside of them, not just exceptions that mean the element is missing.


The columns are present or not as soon as the table is loaded. You can use ds.Tables[config.GlobalVars.Paths].Columns.Contains("columnName") to determine whether or not the column exists.

If a column exists, then for any given row, the column may or may not be null. Use drv.Row.IsNull("columnName") to determine whether that column in that row is null.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • Thanks, I guess that is the purpose of my initial post, I am looking for ways to do this more efficiently. Can you explain how I can check for the elements before accessing them? – Mark Kram Sep 25 '11 at 15:57
  • @@John - I was actually checking the length property of the column: if (drv["SuspressMessages"].ToString().Length > 0). Should I check to see if it is null instead? – Mark Kram Sep 25 '11 at 20:59
  • 1
    Yes, checking for null is closer to the database concept of NULL. Also, remember that the column may not exist (in which case, `["columnName"]` will fail), or may contain a `null` value (in which case `.ToString()` will fail). – John Saunders Sep 26 '11 at 01:33
0

Ok, I just noticed that XmlDataDocument is going to be deprecated soon, so I decided to scrape it and use Linq to XML, and here is my new sopultion

public List<cApplication> GetAppSettings()
        {
            if (!File.Exists(Config.System.XMLFilePath))
            {
                WriteXMLFile();
            }

            try
            {
                XDocument data = XDocument.Load(Config.System.XMLFilePath);

                return (from c in data.Descendants("Application")
                        orderby c.Attribute("Name")
                        select new cApplication()
                        {
                            LocalVersion = (c!=null)?c.Element("Version").Value:string.Empty,
                            RemoteVersion = (c!=null)?c.Element("RemoteVersion").Value:string.Empty,
                            DisableApp = (c!=null)?((YesNo)Enum.Parse(typeof(YesNo), c.Element("DisableApplication").Value, true)):YesNo.No,
                            SuspressMessages = (c != null) ? ((YesNo)Enum.Parse(typeof(YesNo), c.Element("SuspressMessage").Value, true)):YesNo.No
                        }).ToList();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                List<cApplication> l = new List<cApplication>().ToList();
                return l.ToList();
            }
        }
Mark Kram
  • 5,672
  • 7
  • 51
  • 70