如果找不到元素,如何解析xml文件并返回默认值
本文关键字:文件 返回 默认值 xml 何解析 找不到 元素 如果 | 更新日期: 2023-09-27 18:29:19
我用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>
让我们从消除异常"处理"开始。找不到节点是一个"合理的预期"错误,我们将确保不会导致异常。可能应该抛出其他异常,例如根本找不到文件,或者文件不是有效的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
到string
的显式转换将返回null。
当我们这样做的时候,我们只使用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
,而不是原始代码所返回的空字符串。我认为这样更好,因为:
- 它允许调用者区分"提供了设置但为空"answers"未提供设置"
它允许调用者使用null合并运算符来指定默认值:
var setting = ReadConfigurationFile("a", "b", "c", "d") ?? "some default value";