2016-12-16 23 views
0

XmlNodeを受け取り、後続の子がそれぞれ存在し、問題があるかどうかを確認する関数を作成しようとしています。XmlNodeは、chidnodeのリストが存在するかどうかを確認します。

機能は、私が達成したいものを示す

private string GetValueForNodeIfExists(XmlNode node, List<string> childNodes){...} 

の例のように、署名が必要です:私は、ノードの(おそらく、子の子)子が存在するかどうかを知る必要があり を。 "子"という名前の子ノードがあり、 "子"ノードに "grandchild"という名前のノードがあり、そのノードに "greatGrandchild"というノードがある場合、各シーケンスがnullを返すかどうかを確認したいと思いますかではないので、次のことを確認する:私はチェックしています

node['child'] != null 
node['child']['grandchild'] != null 
node['child']['grandchild']['greatGrandchild'] != null 

ノード名は、インデックスは、私がチェックしていたノードの深さに相関List<string>として関数に渡されます。たとえば、上記の例では、リストIは渡されますList<string> checkedasd = new List<String> {"child", "grandchild", "greatGrandchild" };

私はどのようにプログラムごとに['nodeName']式を追加して式を実行するかわかりません。私がそれを理解することができれば、私の戦略はすべてをtryブロックに投げることであり、Null例外が発生した場合、ノードが存在しないことがわかります。

すべてのヘルプは

+0

値は、各ノードが直接の子孫であることがありますか? –

+0

あなたのスキーマに一致する結果が複数見つかった場合( 'IEnumerable '?) –

答えて

0

でコード上記のコードをテストし、あなたがする必要があるすべてdoはXPathを使用します:

private string GetValueForNodeIfExists(XmlNode node, List<string> childNodes) 
{ 
    var xpath = string.Join("/", childNodes.ToArray()); 

    var foundNode = node.SelectSingleNode(xpath); 

    return foundNode != null ? foundNode.InnerText : null; 
} 
あなたはまた、どちらかがNULL値を取得したり、最後に到達するまで、あなたが既に持っていると値によってちょうどループものに拡張することができ

:あなたは常にXmlDocumentに結婚していないとLinq2Xmlを(使用できる場合

private string GetValueForNodeIfExists(XmlNode node, List<string> childNodes) 
{ 
    foreach (var nodeName in childNodes) 
    { 
     if (node != null) 
     { 
      node = node[nodeName]; 
     } 
    } 

    return node != null ? node.InnerText : null; 
} 
4

を高く評価され、私はLinq2Xmlを使用すると、XPATH

var childNodes = new List<string>() { "child", "grandchild", "greatGrandchild" }; 
var xpath = "//" + string.Join("/", childNodes); 

var xDoc = XDocument.Load(filename); 
var xElem = xDoc.XPathSelectElement(xpath); 

if(xElem!=null) //<--- No need for try- catch block 
    Console.WriteLine(xElem.Value); 

PS:私は次のXML

<root> 
    <child> 
     <grandchild> 
      <greatGrandchild> 
       a 
      </greatGrandchild> 
     </grandchild> 
    </child> 
</root> 
+0

XmlNodeでXPathを使用できるようになっているときにLinq2Xmlを使う理由は何ですか?これは、提供された 'node'パラメータを完全に無視するため、OPの要件を満たしません。 – JLRishe

+0

@ JLRisheだから、別のアプローチを提案することは間違っているのですか?それは私がdownvoteを持っているのでとても悪いです:) –

+0

いいえ、間違った答えを提供しています。私がすでに示したように、あなたの答えは、OPがそれを必要とするものではありません。 – JLRishe

1

DotNetFiddle

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

public class Program 
{ 
    public static void Main() 
    { 
     //var xDoc = XDocument.Load(filename); 
     var XDoc = XDocument.Parse(@"<root><a><b><c>value</c></b></a><b><c>no</c></b><a><c>no</c></a></root>"); 
     Console.WriteLine("Params a b c "); 
     foreach(var nodeValue in XDoc.Root.GetValueForNodeIfExists("a", "b", "c")) 
     { 
      Console.WriteLine(nodeValue); 
     } 

     Console.WriteLine("List a b c "); 
     foreach(var nodeValue in XDoc.Root.GetValueForNodeIfExists("a", "b", "c")) 
     { 
      Console.WriteLine(nodeValue); 
     } 
    } 
} 


internal static class XElementExtensions 
{ 
    public static IEnumerable<string> GetValueForNodeIfExists(this XElement node, params string[] childNodesNames) 
    { 
     return GetValueForNodeIfExists(node, childNodesNames.ToList()); 
    } 

    public static IEnumerable<string> GetValueForNodeIfExists(this XElement node, IEnumerable<string> childNodesNames) 
    { 
     IEnumerable<XElement> nodes = new List<XElement> { node }; 

     foreach(var name in childNodesNames) 
     { 
      nodes = FilterChildrenByName(nodes, name); 
     } 

     var result = nodes.Select(n => n.Value); 

     return result; 
    } 

    private static IEnumerable<XElement> FilterChildrenByName(IEnumerable<XElement> nodes, string filterName) 
    { 
     var result = nodes 
      .SelectMany(n => n.Elements(filterName)); 

     Console.WriteLine("Filtering by {0}, found {1} elements", filterName, result.Count()); 

     return result;   
    } 
} 

結果::

または別の選択肢があるかもしれない)新しい何かを学びたいです

PARAMS ABC

フィルタリングは、bで2つの要素

フィルタリングを発見cで1つの要素

フィルタリングを見つけ、見つかった1つの要素

リストABC

aでのフィルタリング、found 2要素

Bによるフィルタリング、cで1つの要素

フィルタリングを発見は、1つの要素

を発見

関連する問題