我在C#中编写了一个简单的方法来解析给定的xml文件并返回特定节点的值。它工作正常,但如果找不到节点而不是抛出异常,我也想返回一个默认值。我怎样才能做到这一点?这种方法可以写得更好吗? 感谢您提供的任何帮助。 约翰
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 = from setting in
configXML.Descendants(root)
.Descendants(section)
select setting.Element(name).Attribute("value").Value;
return result.First();
}
catch (Exception ex)
{
return string.Empty;
}
}
这是我解析的XML文件的示例:
<?xml version='1.0' encoding='utf-8'?>
<automationSettings>
<vmDomain>
<domainName value = "Domain"/>
<domainUsername value = "username"/>
<domainPassword value = "password"/>
</vmDomain>
</automationSettings>
答案 0 :(得分:6)
让我们从摆脱异常“处理”开始吧。未找到的节点是“合理预期”的错误,我们要确保不会导致异常。
,可能会抛出其他异常 - 例如根本找不到文件,或者不是有效的XML接下来,让我们停止使用查询表达式 - 当你只使用select
子句时,它并没有真正为你买任何东西。
下一步,我将停止分配configFilePath
,这可能是一个字段。写这个字段作为副作用对我来说似乎是一个非常糟糕的主意。让我们使用Path.Combine
来组合路径的各个部分......
所以现在我们得到了:
// 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();
}
如果它找不到元素或属性,那么现在将抛出异常。我们可以这样解决:
return configXml.Descendants(root)
.Descendants(section)
.Elements(name)
.Select(x => (string) x.Attribute("value"))
.FirstOrDefault();
现在,如果Elements()
返回一个空序列,则无法选择,FirstOrDefault()
将返回null。如果 是一个元素且它没有value
属性,x.Attribute("value")
将返回null,并且显式转换为XAttribute
到{{1}将返回null。
虽然我们正在使用它,但我们只使用string
进行一次通话,所以让我们通过以下方式进行内联:
configXml
现在,它返回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();
}
而不是原始代码所做的空字符串。我认为这更好,因为:
它允许调用者使用null-coalescing运算符来指定默认值:
null