如何检查节点是否有一个空的单个子元素?

时间:2013-03-07 02:16:47

标签: c# xml linq

我有以下代码,

XDocument doc = XDocument.Parse(input);

var nodes = doc.Element(rootNode)
               .Descendants()
               .Where(n => 
                    (n.Value != "0" 
                    && n.Value != ".00" 
                    && n.Value != "false" 
                    && n.Value != "") 
                    || n.HasElements)
               .Select(n => new 
                { 
                    n.Name, 
                    n.Value, 
                    Level = n.Ancestors().Count() - 1, 
                    n.HasElements 
                });

var output = new StringBuilder();    
foreach (var node in nodes)
{
    if (node.HasElements)
    {
        output.AppendLine(new string(' ', node.Level) + node.Name.ToString() + ":");              
    }
else
{
}

我的问题是,如果我的父节点只有一个空的子节点,我需要插入一个额外的空行。我无法弄清楚如何检查唯一的孩子是否为空。

我可以使用Descendants = n.Descendants().Count()获得后代的数量但是我不知道如何测试这个唯一的孩子是否为空。

2 个答案:

答案 0 :(得分:2)

我的理解是你需要所有只有一个子节点的父节点,并且那个子节点是空的,根据我的理解 -

这是一个简单的测试,它完成了这个:它没有专门使用你的例子,但完成了任务。如果您提供XML的样子,我可以尝试修改我的示例以适合您的帖子,如果以下内容不容易移植到您的项目中:)

(取自控制台应用程序,但实际获取节点的查询应该有效。

static void Main(string[] args)
{
    var xml = @"<root><child><thenode>hello</thenode></child><child><thenode></thenode></child></root>";
    XDocument doc = XDocument.Parse(xml);

    var parentsWithEmptyChild = doc.Element("root")
        .Descendants() // gets all descendants regardless of level
        .Where(d => string.IsNullOrEmpty(d.Value)) // find only ones with an empty value
        .Select(d => d.Parent) // Go one level up to parents of elements that have empty value
        .Where(d => d.Elements().Count() == 1); // Of those that are parents take only the ones that just have one element


    parentsWithEmptyChild.ForEach(Console.WriteLine);

    Console.ReadKey();
}

这只返回第二个节点,它只包含一个空节点,其中假定为一个string.Empty的值。

答案 1 :(得分:0)

我试图自己解决这个问题,这就是我想出来的:

XDocument doc = XDocument.Parse(input);

         var nodes = doc.Element(rootNode).Descendants()
             .Where(n => (n.Value != "0" && n.Value != ".00" && n.Value != "false" && n.Value != "") || n.HasElements)
             .Select(n => new { n.Name, n.Value, Level = n.Ancestors().Count() - 1, 
                n.HasElements, Descendants = n.Descendants().Count(), 
                FirstChildValue = n.HasElements?n.Descendants().FirstOrDefault().Value:"" });

         var output = new StringBuilder();

         foreach (var node in nodes)
         {            
            if (node.HasElements)
            {               
               output.AppendLine(new string(' ', node.Level) + node.Name.ToString() + ":");
               if (0 == node.Level && 1 == node.Descendants && String.IsNullOrWhiteSpace(node.FirstChildValue))
                  output.AppendLine("");
            }