简体   繁体   English

删除XML节点集合中的空/空白元素

[英]Remove empty/blanks elements in collection of XML nodes

I have an XML document like this: 我有一个像这样的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>

I'm trying to iterate each node and do the following: 我正在尝试迭代每个节点并执行以下操作:

  1. Throw out any elements that are empty/blank. 扔掉任何空/空白的元素。
  2. Generate new Node with only elements containing values. 仅使用包含值的元素生成新节点。
  3. Send the resulting doc to different web service. 将生成的文档发送到不同的Web服务。

The part I'm struggling with is how to iterate through each node and check each element for null values. 我正在努力的部分是如何遍历每个节点并检查每个元素的空值。

I've been testing this code out at http://rextester.com/runcode but can't seem to figure it out: 我一直在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++;
}

Based on the above XML input, I'm hoping to get the following output: 根据上面的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>

I'm not sure if I'm using the right methods to iterate over the nodes and elements. 我不确定我是否使用正确的方法迭代节点和元素。

A single one-liner could do the job, no need to iterate over all elements. 单个单行可以完成工作,无需迭代所有元素。 Here it goes: 在这里:

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

Tester 测试仪

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

And it also could be tested here 它也可以在这里测试

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

This one line will not throw out empty parent tags that are full of empty children tags. 这一行不会抛出充满空子标记的空父标记。 It will just remove their children , which may or may not be appropriate in your situation. 它只会移除他们的孩子,这可能适合您的情况,也可能不适合您的情况。 It is a really simple change to achieve this you simply have to start removing from the lowest level first. 实现这一目标是一个非常简单的变化,您只需要首先从最低级别开始删除。 Something like 就像是

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

Thanks Nyerguds for the attribute suggestion. 感谢Nyerguds的属性建议。

在VB中我需要再次找到它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM