0

ここにXMLがあります

この ResultCode 属性を取得します。エラーの場合は、すべての製品の子ノードを探します

   <PRODUCT Action="Result" ResultCode="ERROR" ResultText="An error occurred in a child   element.">            <PNO>9723151113</PNO>
       <CATALOG_NO ResultCode="ERROR" ResultText="Invalid entry for this field.">1134</CATALOG_NO>
   </PRODUCT>

したがって、最初にノードの属性に ERROR があるかどうかを確認し、子ノードを選択して子孫の子ノードにエラーがあるかどうかを確認し、LINQ を使用してそのノードを取得します。上記のように、Cust の下のすべてのノードを探して属性「ResultCode」をチェックし、エラー値がある場合はそのノードを選択し、正確なエラーを見つけるためにその子ノードを探します。Cust -> エラーのあるノードはありますか? -> 製品 => 製品を選択 => 製品の下のすべての子ノードを調べる => ERROR 属性ノードを選択します。

ループ内のすべてのノードを解析するロジックを配置したくないので、linq を使用するのは簡単だと思います。Linq クエリを使用してこれを達成する方法はありますか?

4

3 に答える 3

1

これを試してください:

var xDoc = XDocument.Load(@"YourXML.xml");
var xElementWithErrors = (from xElem in doc.Descendants()
                          where xElem.Attribute("ResultCode").Value == "ERROR"
                          select xElem).ToList();

ResultCode が "ERROR" の Product タグを持つすべての子がリストに入力されますxElementWithErrors

于 2013-04-18T00:53:18.987 に答える
0

あなたの質問が正しいと理解できれば、 attribute を持つ最も内側の要素のみを取得したいと考えていますResultCode="ERROR"。の子要素があるため、サンプルデータ<PRODUCT>は結果に含まれるべきではありませんResultCode="ERROR"

このDescendantsメソッドは、ドキュメント内のすべての子孫要素を返します。したがって、属性のみによるフィルタリングには、<PRODUCT>ノードが含まれます。したがって、各要素の子のチェックを追加する必要があります。

var doc = XDocument.Load("Test.xml");

var errors = doc.Descendants()
                .Where(e => e.Attribute("ResultCode") != null &&
                            e.Attribute("ResultCode").Value == "ERROR" &&
                            !e.Elements().Any(c => c.Attribute("ResultCode") != null &&
                                                   c.Attribute("ResultCode").Value == "ERROR"));

これは、エラーのある子を持たない要素のみを返します。

ResultCodeXML の各ノードに属性がある場合は、null のチェックを省略できることに注意してください。そうでない場合は、NullReferenceException. そのチェックのための小さなヘルパーメソッドを書くことをお勧めします:

public static bool HasError(XElement element)
{
    var resultCode = element.Attribute("ResultCode");
    return resultCode != null && resultCode.Value == "ERROR";
}

var errors = doc.Descendants()
                .Where(e => HasError(e) && !e.Elements().Any(c => HasError(c)));

ResultCode="ERROR"親にエラーがない場合でも、これは要素を返すことに注意してください。

親にもエラーがある場合にのみ要素を結果に含める必要があるという要件がある場合、および XML が常にそのように形成されるかどうかわからない場合は、再帰関数を記述する必要があります。

public static IEnumerable<XElement> InnermostErrors(XElement root)
{
    var resultCode = root.Attribute("ResultCode");
    if (resultCode == null || resultCode.Value != "ERROR")
    {
        yield break;
    }

    var childrenWithError = root.Elements().Where(e => HasError(e));
    if (!childrenWithError.Any())
    {
        yield return root;
    }

    foreach (var inner in childrenWithError.SelectMany(e => InnermostErrors(e)))
    {
        yield return inner;
    }
}
于 2013-04-18T17:32:20.043 に答える
0

XDocument を使用すると、まず属性値が のノードをチェックしERROR、次にその親を次のように選択できます。

var doc = XDocument.Load(...);

var result = doc.Descendants()
    .Where(n => n.Attribute("ResultCode").Value == "ERROR")
    .Select(n => new { n.Parent, ActualNode = n });

が null でないかどうかを確認Parentし、実際に処理したくないノードのタイプでフィルタリングすることもできます。あなたがここで達成しようとしていることについてもっと知らなければ、あなたを助けることは難しい. うまくいけば、これで始められるでしょう。

于 2013-04-18T00:41:05.153 に答える