在XML节点的集合中删除空/空白元素(Remove empty/blanks elements in

2019-07-18 16:35发布

我有一个这样的XML文档:

<magento_api>
    <data_item>
        <code>400</code>
        <message>Attribute weight is not applicable for product type Configurable Product</message>
    </data_item>
    <data_item>
        <code>400</code>
        <message>Resource data pre-validation error.</message>
    </data_item>
    <data_item>
        <code>1</code>
        <message></message>
    </data_item>
    <data_item>
        <code></code>
        <message>No code was given</message>
    </data_item>
</magento_api>

我试图遍历每个节点并执行以下操作:

  1. 扔掉那些空/空的任何元素。
  2. 生成包含值仅元素新的节点。
  3. 发送所产生的文档为不同的网络服务。

我挣扎的部分是如何通过每个节点迭代并检查每个元素为空值。

我已经测试了这个代码在http://rextester.com/runco​​de ,但似乎无法推测出来:

Console.WriteLine("Querying tree loaded with XElement.Load");
Console.WriteLine("----");
XElement doc = XElement.Parse(@"<magento_api>
          <data_item>
            <code>400</code>
            <message>Attribute weight is not applicable for product type Configurable Product</message>
          </data_item>
          <data_item>
            <code>400</code>
            <message>Resource data pre-validation error.</message>
          </data_item>
          <data_item>
            <code>1</code>
            <message></message>
          </data_item>
          <data_item>
            <code></code>
            <message>No code was given</message>
          </data_item>
    </magento_api>");

int counter = 1;
IEnumerable<XNode> nodes =
    from nd in doc.Nodes()
    select nd;
foreach (XNode node in nodes)
{
    Console.WriteLine(counter + "-" + node);
    IEnumerable<XElement> elements =
    from el in node //this is where I've been trying various methods, but no dice.
    select el;
    foreach (XElement e in elements)
    {
           Console.WriteLine(counter + "-" + e.Name + "-" + e.Value + "\r\n");
    }
    counter++;
}

基于上述XML输入,我希望能得到以下的输出:

<magento_api>
    <data_item>
        <code>400</code>
        <message>Attribute weight is not applicable for product type Configurable Product</message>
    </data_item>
    <data_item>
        <code>400</code>
        <message>Resource data pre-validation error.</message>
    </data_item>
    <data_item>
        <code>1</code>
    </data_item>
    <data_item>
        <message>No code was given</message>
    </data_item>
</magento_api>

我不知道如果我用正确的方法来遍历节点和元素。

Answer 1:

单一个班轮可以做的工作,无需遍历所有元素。 这里有云:

doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();

测试仪

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    public class TestRemove
    {
        public static void Main() {
            Console.WriteLine("----OLD TREE STARTS---");
            XElement doc = XElement.Parse(@"<magento_api>
                                              <data_item>
                                                <code>400</code>
                                                <message>Attribute weight is not applicable for product type Configurable Product</message>
                                              </data_item>
                                              <data_item>
                                                <code>400</code>
                                                <message>Resource data pre-validation error.</message>
                                              </data_item>
                                              <data_item>
                                                <code>1</code>
                                                <message></message>
                                              </data_item>
                                              <data_item>
                                                <code></code>
                                                <message>No code was given</message>
                                              </data_item>
                                        </magento_api>");
            Console.Write(doc.ToString());
            Console.WriteLine("");
            Console.WriteLine("----OLD TREE ENDS---");
            Console.WriteLine("");
            doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
            Console.WriteLine("----NEW TREE STARTS---");
            Console.Write(doc.ToString());
            Console.WriteLine("");
            Console.WriteLine("----NEW TREE ENDS---");
            Console.ReadKey();
        }
    }
}

而且它也可以测试在这里



Answer 2:

doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove(); 

这一条线就不会丢的是,满空的子标签的空父标签。 这将只是删除自己的孩子,这可能会或可能不会在您的具体情况适当的。 这是一个非常简单的改变来实现这一点,你只需要开始从最低水平先删除。 就像是

foreach(XElement child in doc.Descendants().Reverse())
{
    if(!child.HasElements && string.IsNullOrEmpty(child.Value) && !child.HasAttributes) child.Remove();
}

感谢Nyerguds为属性的建议。



Answer 3:

在VB中的情况下,我需要重新找到它:

doc.Descendants().Where(Function(e) String.IsNullOrEmpty(e.Value)).Remove()


文章来源: Remove empty/blanks elements in collection of XML nodes