I am working on a c# console application which has an xml config file which contains the settings for the program.
I wanted to add a comment to the xml file to show what values you can use for a particular settings using <!--My Comment-->. For some reason when I put this in, its as if C# then thinks that this is end of the file and no other part of the file is read, there’s no errors being thrown and the program doesn’t stop responding it continues running the rest of the code.
Below is the config file.
<?xml version="1.0" encoding="utf-8" ?>
<options>
<database>
<item key="server" value="localhost" />
<item key="database" value="emailserver" />
<item key="username" value="myusername" />
<item key="password" value="mypassword" />
<item key="port" value="3306" />
</database>
<EmailServer>
<item key="logFile" value="email_server.txt" />
<!--You can use fileCopy or database-->
<item key="logManageMode" value="fileCopy" />
<item key="ip_address" value="127.0.0.1" />
<item key="smtpPort" value="26" />
<item key="requireAuthentication" value="false" />
</EmailServer>
</options>
If I don’t put that comment in it reads in the entire file. Below is the code that reads the XML file.
public Dictionary<string, string> readConfig(string sectionName, bool soapService=false, Dictionary<string, string> config=null)
{
Dictionary<string, string> newConfig = null;
if (config == null)
{
newConfig = new Dictionary<string, string>();
}
//Dictionary<string, string> config = new Dictionary<string, string>();
try
{
XmlDocument configXml = new XmlDocument();
string configPath = "";
if (soapService)
{
string applicationPath = HttpContext.Current.Server.MapPath(null);
configPath = Path.Combine(applicationPath, "config.xml");
configXml.Load(configPath);
}
else
{
configXml.Load("config.xml");
}
XmlNodeList options = configXml.SelectNodes(string.Format("/options/{0}", sectionName));
XmlNodeList parameters = configXml.GetElementsByTagName("item");
foreach (XmlNode option in options)
{
foreach (XmlNode setting in option)
{
string key = setting.Attributes["key"].Value;
string value = setting.Attributes["value"].Value;
if (config == null)
{
newConfig.Add(key, value);
}
else
{
config.Add(key, value);
}
}
}
}
catch (KeyNotFoundException ex)
{
Console.WriteLine("Config KeyNotFoundException: {0}", ex.Message);
}
catch (XmlException ex)
{
Console.WriteLine("Config XmlException: {0}", ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Config Exception: {0}", ex.Message);
Console.WriteLine("StackTrace: {0}", ex.StackTrace);
}
if (config == null)
{
return newConfig;
}
return config;
}
Thanks for any help you can provide.
your comment is a node. so when you loop over the nodes:
you are tripping your try/catch block at the commebnt because that node does not contain the “key” or “value” attributes.
You can use the
NodeTypeproperty to determine if the node is a comment or not. For example:Another option is to continue if the node is not an element:
As per Tomalak:
Actually this is just as brittle as the OP’s original code. Insert a different node type into the XML than a comment and it will blow up again. Just select a specific XmlNodeList inside the loop:
XmlNodeList settings = option.SelectNodes("item[@key and @value]");