c# - How to parse an xml file and return default value if no element found -


i wrote simple method in c# parse given xml file , return value of specific node. works fine i'd return default value if node not found instead of throwing exception. how can this? can method written better? offered. john

public static string readconfigurationfile(string configurationfilename, string root, string section, string name) {     try     {         string currentdirectory = path.getdirectoryname(system.reflection.assembly.getexecutingassembly().location);         configfilepath = directory.getparent(currentdirectory) + configurationfolder + configurationfilename;          xdocument configxml = xdocument.load(configfilepath);         var result = setting in                          configxml.descendants(root)                             .descendants(section)                      select setting.element(name).attribute("value").value;         return result.first();     }     catch (exception ex)     {         return string.empty;     } } 

here's sample of xml file parse:

<?xml version='1.0' encoding='utf-8'?> <automationsettings>     <vmdomain>         <domainname value = "domain"/>         <domainusername value = "username"/>         <domainpassword value = "password"/>     </vmdomain> </automationsettings> 

let's start getting rid of exception "handling". node not being found "reasonable expect" error, , 1 we're going ensure doesn't result in exception. other exceptions - such file not being found @ all, or not being valid xml - should thrown.

next, let's stop using query expression - when you're using select clause, doesn't buy anything.

as next step, i'm going stop assigning configfilepath presumably field. writing field side-effect seems bad idea me. let's use path.combine combine bits of path well...

so we've got:

// work in progress! public static string readconfigurationfile(     string configurationfilename,     string root,     string section,     string name) {     string currentdirectory = path.getdirectoryname(         assembly.getexecutingassembly().location);     var fullconfigpath = path.combine(         directory.getparent(currentdirectory),         configurationfolder,         configurationfilename);      var configxml = xdocument.load(fullconfigpath);     return configxml.descendants(root)                     .descendants(section)                     .select(x => x.element(name).attribute("value").value                     .first(); } 

that's going throw exception if can't find either element or attribute. can fix this:

return configxml.descendants(root)                 .descendants(section)                 .elements(name)                 .select(x => (string) x.attribute("value"))                 .firstordefault(); 

now, if elements() returns empty sequence, there'll nothing select , firstordefault() return null. if there is element , doesn't have value attribute, x.attribute("value") return null, , explicit conversion xattribute string return null.

while we're @ it, we're using configxml 1 call, let's inline that, leaving with:

public static string readconfigurationfile(     string configurationfilename,     string root,     string section,     string name) {     string currentdirectory = path.getdirectoryname(         assembly.getexecutingassembly().location);     var fullconfigpath = path.combine(         directory.getparent(currentdirectory),         configurationfolder,         configurationfilename);      return xdocument.load(fullconfigpath)                     .descendants(root)                     .descendants(section)                     .elements(name)                     .select(x => (string) x.attribute("value"))                     .firstordefault(); } 

now, returns null rather empty string original code does. i'd argue that's better, because:

  • it allows caller differentiate "the setting provided empty" "the setting wasn't provided"
  • it allows caller use null-coalescing operator specify default value:

    var setting = readconfigurationfile("a", "b", "c", "d") ?? "some default value"; 

Comments

Popular posts from this blog

ruby - Trying to change last to "x"s to 23 -

jquery - Clone last and append item to closest class -

css - Can I use the :after pseudo-element on an input field? -