使用 XDocument 检查文件中是否存在 xml 部分

Check if an xml section exist in a file using XDocument

我有一些代码可以读取 xml 文件。但是,它在第​​ 3 个 IF 语句中触发错误:

if (xdoc.Root.Descendants("HOST").Descendants("Default")
    .FirstOrDefault().Descendants("HostID")
    .FirstOrDefault().Descendants("Deployment").Any())

错误:

System.NullReferenceException: Object reference not set to an instance of an object.

那是因为在这个特定文件中没有 [HOST] 部分。

我假设在第一个 IF 语句中,如果它没有找到任何 [HOST] 部分,它就不会进入该语句,因此我不应该得到这个错误。有没有办法先检查一个部分是否存在?

XDocument xdoc = XDocument.Load(myXmlFile);

if (xdoc.Root.Descendants("HOST").Any())
{
    if (xdoc.Root.Descendants("HOST").Descendants("Default").Any())
    {
        if (xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault().Descendants("HostID").FirstOrDefault().Descendants("Deployment").Any())
        {
            if (xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault().Descendants("HostID").Any())
            {
                var hopsTempplateDeployment = xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault().Descendants("HostID").FirstOrDefault().Descendants("Deployment").FirstOrDefault();
                deploymentKind = hopsTempplateDeployment.Attribute("DeploymentKind");
                host = hopsTempplateDeployment.Attribute("HostName");
            }
        }
    }
}

在此 if 块的主体内...

if (xdoc.Root.Descendants("HOST").Descendants("Default").Any())
{
    if (xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault().Descendants("HostID").FirstOrDefault().Descendants("Deployment").Any())
    {
        if (xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault().Descendants("HostID").Any())
        {
            var hopsTempplateDeployment = xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault().Descendants("HostID").FirstOrDefault().Descendants("Deployment").FirstOrDefault();
            deploymentKind = hopsTempplateDeployment.Attribute("DeploymentKind");
            host = hopsTempplateDeployment.Attribute("HostName");
        }
    }
}

...您已确定元素 <Root>/HOST/Default 存在。然而,您 知道 <Root>/HOST/Default/HostId/Deployment 是否存在。如果不是,您将得到一个 NullReferenceException,就像您使用 FirstOrDefault 时遇到的那样。通常建议在您希望元素存在的情况下使用 First,这至少会给您一个更好的错误消息。

如果您希望元素不存在,一个简单的解决方案是沿相应的 LINQ2XML 轴使用 ?.

var hopsTemplateDeployment =
    xdoc.Root.Descendants("HOST").Descendants("Default").FirstOrDefault()
    ?.Descendants("HostID").FirstOrDefault()
    ?.Descendants("Deployment").FirstOrDefault();
if (hopsTemplateDeployment != null)
{
    deploymentKind = hopsTemplateDeployment.Attribute("DeploymentKind");
    host = hopsTemplateDeployment.Attribute("HostName");
}

它还会为您节省嵌套的 if 个子句链。