检查全局 XElement 是否为 null

发布于 2024-12-12 03:27:00 字数 1375 浏览 0 评论 0原文

我有一个类负责读取和保存 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 中不存在某些元素,我会得到 System.NullReferenceException 。所以我需要检查元素是否为 null 。这是实现此目的的一种方法:

var value = Configuration.Element("LaunchDebugger").Value;
if (value != null)
    LaunchDebugger = Convert.ToBoolean(value);
else
    throw new Exception("LaunchDebugger element missing from xml!");

但是对每个元素都这样做就太多了。所以我需要一些好主意来简化这个系统,这样它就不会变成 1000 行代码。

编辑:编辑了最后一个代码片段,想法不是设置默认值,想法是通知用户 xml 中缺少此元素。

I have a class what takes care of reading and holding the XML file.
Right now a simple version of it looks like this:

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);
     }
 }

And there will be more later. so the problem is that if some element does not exist in xml i get System.NullReferenceException. So i need to check if the element is null or not. Heres one way to do this:

var value = Configuration.Element("LaunchDebugger").Value;
if (value != null)
    LaunchDebugger = Convert.ToBoolean(value);
else
    throw new Exception("LaunchDebugger element missing from xml!");

But doing that for every element would be just too much. So i need some good ideas how to simplify this system so it wouldn't end up in 1000 lines of code.

EDIT: Edited the last code snippet, the idea was not to set a default value, idea was to notify the user that this element whats null is missing from the xml.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

路还长,别太狂 2024-12-19 03:27:00

这里的想法直接来自 abatischev 的回答,所以他值得称赞。

根据 Microsoft 此处的规定,您可以直接转换 XElement< /code> 到您想要的类型。

LaunchDebugger = (bool?)Configuration.Element("LaunchDebugger");

如果您想处理 null 情况,我想您可以这样做

LaunchDebugger = (bool)(Configuration.Element("LaunchDebugger") ?? true);

,或者可能

LaunchDebugger = (bool)(Configuration.Element("LaunchDebugger") ?? false);

取决于您的业务逻辑。如果您对特定类型执行相同的合并场景,则可能适合将这个衬里包装在方法、扩展或其他方式中,但我不确定它会增加很多。

The idea here comes directly from abatischev's answer so he deserves the credit.

As perscribed by Microsoft here you can just cast the XElement to the type you desire.

LaunchDebugger = (bool?)Configuration.Element("LaunchDebugger");

if you want to handle the null case I guess you could do

LaunchDebugger = (bool)(Configuration.Element("LaunchDebugger") ?? true);

or perhaps

LaunchDebugger = (bool)(Configuration.Element("LaunchDebugger") ?? false);

depending on your business logic. If you do the same coalescene for a specific type it may be appropriate to wrap this one liner in a method, extension or otherwise but I'm uncertain it would add much.

撩发小公举 2024-12-19 03:27:00
(bool)Configuration.Element("LaunchDebugger")

或者

(bool?)Configuration.Element("LaunchDebugger")

不应该抛出异常。

请参阅 MSDN:

(bool)Configuration.Element("LaunchDebugger")

or

(bool?)Configuration.Element("LaunchDebugger")

should not throw exception.

See MSDN:

这个俗人 2024-12-19 03:27:00

我有一个扩展方法,用于此类事情:

    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);

I have an extension method that I use for just this kind of thing:

    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();
    }

It gives you the casting required and also a default value factory.

Here's how you'd use it:

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);
流年里的时光 2024-12-19 03:27:00

将逻辑提取到方法中,并具有用于 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);
    }

Extract the logic to a method and have overloaded methods for Int32,boolean and other data types conversion.

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);
    }
鹿港巷口少年归 2024-12-19 03:27:00

您可以定义一个方法来为您提取值并在那里对 null 进行一些检查。因此,将值检索包装在您自己的方法中,如下所示:

public string GetXMLValue(XElement config, string elementName){
    var element = Configuration.Element(elementName);

    if(element == null)
        return String.Empty;

    return element.Value;
}

当然,您可以扩展它以正确解析布尔值等。

You can define a method to extract the value for you and do some checking on null there. So wrap the value retrieval in your own method like so:

public string GetXMLValue(XElement config, string elementName){
    var element = Configuration.Element(elementName);

    if(element == null)
        return String.Empty;

    return element.Value;
}

Of course you can extend this to work correctly with parsing to boolean etc.

尤怨 2024-12-19 03:27:00

外部方法怎么样:

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

正如其他人所说,您可以使用 ?? 运算符为 null 提供值。不过,这不是嵌套的,因此:

LaunchDebugger = XmlConvert.ToBoolean(Configuration.Element("LaunchDebugger").Value) ?? false;

如果 XML 文件中没有此类元素,则会抛出 NullReferenceException。

How about an external method:

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;
    }
}

I've tested this with 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        

To produce this result:

False
True
False
False
False

Add more such methods for other types and also add AsBoolean(defaultValue), as that can come in handy, when you want to default to true!

As others have stated, you can use the ?? operator to provide a value for null. This doesn't nest, though, so:

LaunchDebugger = XmlConvert.ToBoolean(Configuration.Element("LaunchDebugger").Value) ?? false;

will through a NullReferenceException if there is no such element in the XML file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文