12

次のような 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. 結果のドキュメントを別の Web サービスに送信します。

私が苦労している部分は、各ノードを反復処理し、各要素の null 値をチェックする方法です。

私は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>

ノードと要素を反復するために正しい方法を使用しているかどうかはわかりません。

4

3 に答える 3

36

すべての要素を反復する必要はなく、単一のワンライナーで仕事をすることができます。ここに行きます:

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

また、ここでテストすることもできます

于 2013-01-25T06:32:06.473 に答える
9
doc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove(); 

この 1 行は、空の子タグでいっぱいの空の親タグをスローしません。children を削除するだけです。これは、状況に適している場合とそうでない場合があります。これを実現するのは非常に簡単な変更です。最初に最下位レベルから削除を開始するだけです。何かのようなもの

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

属性の提案をしてくれた Nyerguds に感謝します。

于 2016-06-03T12:39:08.047 に答える