使用 xlinq 删除所有空元素

发布于 2024-08-09 15:18:02 字数 686 浏览 2 评论 0原文

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

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

换句话说;如果我删除所有恰好是

  • 标签内唯一元素的 标签,如何删除空的
  • ;?
  • 之前:

    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>
    

    I'm doing some transforms using xlinq and some of those transforms can result in leaving empty elements in the document.

    Once I am done all of those transforms, how can I query an xdocument for all empty elements?

    In other words; if I remove all <a> tags which happen to be the only element inside an <li> tag, how do I remove the empty <li>?

    Before:

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

    After:

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

    I would prefer:

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

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

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

    发布评论

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

    评论(5

    无法言说的痛 2024-08-16 15:18:02

    检查元素是否没有属性s 和 没有元素 还不够。您需要检查元素是否真正为空(绝对没有内容)。 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();
    

    Checking if element doesn't have attributes and doesn't have elements is not enough. You need to check if an element is truly empty (absolutely no content). XElement has a property, that actually helps you do that - 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();
    
    柒七 2024-08-16 15:18:02

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

    Give XmlNodeList to this function an try this code
    Hope this will work to remove all empty element and attribute from XMl file

        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);
                }
            }
        }
    
    分开我的手 2024-08-16 15:18:02

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

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

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

    The best I could come up with was...

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

    Then I realized that was a bad idea, it was removing too much but I didn't take the time to figure out why.

    蓦然回首 2024-08-16 15:18:02

    这里接受的答案并不完全正确。具体来说,它只会删除 形式的元素,并保留 之类的元素。

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

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

    The accepted answer here is not quite right. Specifically, it will only remove elements that are in the form <foo /> and will leave elements like <foo></foo>.

    As such, here is a complete solution:

    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();
        }
    }
    
    血之狂魔 2024-08-16 15:18:02

    检查 IsEmpty 和 HasAttributes 更有帮助。

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

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

          <Participant xsi:nil="true"/>
    

    Checking for both IsEmpty and HasAttributes is more helpful.

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

    IsEmpty will return true for elements with just attributes. Eg:

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