使用xlinq删除所有空元素

时间:2009-11-03 15:43:43

标签: xml linq-to-xml

我正在使用xlinq进行一些转换,其中一些转换可能会导致在文档中留下空元素。

完成所有这些转换后,如何查询xdocument以查找所有空元素?

换句话说;如果我删除了恰好是<a>标记内唯一元素的所有<li>标记,如何删除空<li>

在:

XDocument.Parse(@"<body>
   <ul><li><a href="#">Joy</a></li></ul>
   <p>Hi.</p>
</body>").Descendants("a").Remove();

后:

<body>
   <ul><li/></ul>
   <p>Hi.</p>
</body>

我更愿意:

<body>
   <p>Hi.</p>
</body>

5 个答案:

答案 0 :(得分:10)

检查元素doesn't have attributedoesn't have elements是否不够。您需要检查元素是否真的为空(绝对没有内容)。 XElement有一个属性,实际上可以帮助你做到这一点 - XElement.IsEmpty

var document = XDocument.Parse(@"<body><ul><li><a href='#'>Joy</a></li></ul><p>Hi.</p></body>");
document.Descendants("a").Remove();

var emptyElements = from element in document.Descendants()
                    where element.IsEmpty
                    select element;

while (emptyElements.Any())
    emptyElements.Remove();

答案 1 :(得分:1)

尝试使用此代码将XmlNodeList提供给此函数 希望这可以从XMl文件中删除所有空元素和属性

    public static XmlNode RemoveNullElement(XmlNodeList xmlNodeList)
    {
        if (xmlNodeList.Count > 0)
        {
            foreach (XmlNode xmlnode in xmlNodeList)
            {
                RemoveNullChildAndAttibute(xmlnode);
                return xmlnode;
            }
        }

        return null;
    }


    public static void RemoveNullChildAndAttibute(XmlNode xmlNode)
    {
        if (xmlNode.HasChildNodes)
        {
            for (int xmlNodeCount = xmlNode.ChildNodes.Count - 1; xmlNodeCount >= 0; xmlNodeCount--)
            {
                RemoveNullChildAndAttibute(xmlNode.ChildNodes[xmlNodeCount]);
            }
        }
        else if (xmlNode.Attributes.Count == 0)
        {
            if (xmlNode.ParentNode != null)
            {
                xmlNode.ParentNode.RemoveChild(xmlNode);
            }
        }
    }

答案 2 :(得分:0)

我能想到的最好的是......

var emptyElements = 
    from element in document.Descendants()
    where !element.Attributes().Any() && !element.Elements().Any()
    select element;


while(emptyElements.Any())
    emptyElements.Remove();

然后我意识到这是一个坏主意,它删除了太多,但我没有花时间弄清楚原因。

答案 3 :(得分:0)

这里接受的答案不太正确。具体来说,它只会移除<foo />格式的元素,并会留下<foo></foo>等元素。

因此,这是一个完整的解决方案:

public static void RemoveEmptyDescendants(this XNode node)
{
    var empty = from e in node.Descendants()
                where !e.Nodes().Any() && !e.Attributes().Any()
                select e;

    while (empty.Any())
    {
        empty.Remove();
    }
}

答案 4 :(得分:0)

检查IsEmpty和HasAttributes更有帮助。

        var emptyElements = document.Descendants()
                             .Where(element => element.IsEmpty 
                                             && !element.HasAttributes);
        while (emptyElements.Any())
        {
            emptyElements.Remove();
        }

对于仅具有属性的元素,IsEmpty将返回true。例如:

      <Participant xsi:nil="true"/>