检查XElement是否全局为null
本文关键字:null 全局 是否 XElement 检查 | 更新日期: 2023-09-27 18:12:20
我有一个类负责读取和保存XML文件。现在它的一个简单版本是这样的:
public class EstEIDPersoConfig
{
public bool LaunchDebugger { get ; set; }
public string Password { get; set; }
public int Slot { get; set; }
public string Reader { get; set; }
public string TestInput { get; set; }
public bool Logging { get; set; }
public EstEIDPersoConfig()
{
XElement xml = XElement.Load(myxml.xml);
XElement Configuration = xml.Element("Configuration");
LaunchDebugger = Convert.ToBoolean(Configuration.Element("LaunchDebugger").Value);
Password = Configuration.Element("Password").Value;
Slot = Convert.ToInt32(Configuration.Element("Slot").Value);
Reader = Configuration.Element("Reader").Value;
TestInput = Configuration.Element("TestInput").Value;
Logging = Convert.ToBoolean(Configuration.Element("Logging").Value);
}
}
稍后还会有更多。所以问题是,如果xml中不存在某个元素,我会得到CCD_ 1。所以我需要检查元素是否是null
。有一种方法可以做到这一点:
var value = Configuration.Element("LaunchDebugger").Value;
if (value != null)
LaunchDebugger = Convert.ToBoolean(value);
else
throw new Exception("LaunchDebugger element missing from xml!");
但对每一个元素都这样做太过分了。所以我需要一些好的想法来简化这个系统,这样它就不会在1000行代码中结束。
EDIT:编辑了最后一个代码片段,想法不是设置默认值,而是通知用户xml中缺少这个元素whats-null。
这里的想法直接来自于abatischev的回答,因此他值得称赞。
正如微软在这里所描述的那样,你可以将XElement
转换为你想要的类型。
LaunchDebugger = (bool?)Configuration.Element("LaunchDebugger");
如果你想处理null
案件,我想你可以做
LaunchDebugger = (bool)(Configuration.Element("LaunchDebugger") ?? true);
或者
LaunchDebugger = (bool)(Configuration.Element("LaunchDebugger") ?? false);
这取决于您的业务逻辑。如果你对一个特定的类型做同样的聚结,那么在一个方法、扩展或其他方法中包装这一行可能是合适的,但我不确定它会增加很多。
(bool)Configuration.Element("LaunchDebugger")
或
(bool?)Configuration.Element("LaunchDebugger")
不应引发异常。
请参阅MSDN:
- XElement显式转换(XElement到
Boolean
( - XElement显式转换(XElement到
Nullable<Boolean>
(
我有一个扩展方法,用于这类事情:
public static T GetValue<T>(
this XElement @this,
XName name,
Func<XElement, T> cast,
Func<T> @default)
{
var e = @this.Element(name);
return (e != null) ? cast(e) : @default();
}
它为您提供了所需的铸造以及默认值工厂。
以下是使用方法:
LaunchDebugger = Configuration.GetValue("LaunchDebugger",
x => Convert.ToBoolean(x), () => false);
Password = Configuration.GetValue("CMKPassword", x => (string)x, () => "");
Slot = Configuration.GetValue("CMKSlot", x => (int)x, () => -1);
Reader = Configuration.GetValue("Reader", x => (string)x, () => "");
TestInput = Configuration.GetValue("TestInput", x => (string)x, () => "");
Logging = Configuration.GetValue("Logging",
x => Convert.ToBoolean(x), () => false);
将逻辑提取到方法中,并具有用于Int32、boolean和其他数据类型转换的重载方法。
public static void GetElementValue(XElement xElement, string parameter, out bool value)
{
var stringValue = xElement.Element(parameter).Value;
value = false;
if (value != null)
value = Convert.ToBoolean(stringValue);
}
您可以定义一个方法来为您提取值,并在那里对null进行一些检查。因此,用您自己的方法包装价值检索,如下所示:
public string GetXMLValue(XElement config, string elementName){
var element = Configuration.Element(elementName);
if(element == null)
return String.Empty;
return element.Value;
}
当然,您可以将其扩展为正确的解析布尔值等。
外部方法如何:
public static class XElementExtensions
{
public static bool AsBoolean(this XElement self, bool defaultValue)
{
if (self == null)
{
return defaultValue;
}
if (!string.IsNullOrEmpty(self.Value))
{
try
{
return XmlConvert.ToBoolean(self.Value);
}
catch
{
return defaultValue;
}
}
return defaultValue;
}
}
我已经用SnippetCompiler:测试过了
XElement test = new XElement("test",
new XElement("child1"),
new XElement("child2", new XText("true")),
new XElement("child3", new XText("false")),
new XElement("child4", new XText("rubbish")));
WL(test.Element("child1").AsBoolean(false)); // note, "child1" has no value (or is `""`)
WL(test.Element("child2").AsBoolean(false));
WL(test.Element("child3").AsBoolean(false));
WL(test.Element("child4").AsBoolean(false));
WL(test.Element("child5").AsBoolean(false)); // note, "child5" doesn't exist
产生此结果:
False
True
False
False
False
为其他类型添加更多这样的方法,并添加AsBoolean(defaultValue)
,因为当您想默认为true
时,这会很有用!
正如其他人所说,您可以使用??
运算符为System.NullReferenceException
0提供一个值。不过,这并没有嵌套,所以:
LaunchDebugger = XmlConvert.ToBoolean(Configuration.Element("LaunchDebugger").Value) ?? false;
如果XML文件中没有这样的元素,则将通过CCD_ 11。