2009-03-22 10 views
176

मैं इस एक्सएमएल फ़ाइल को पढ़ने के लिए मिल गयाLINQ एक्सएमएल

<root> 
    <level1 name="A"> 
     <level2 name="A1" /> 
     <level2 name="A2" /> 
    </level1> 
    <level1 name="B"> 
     <level2 name="B1" /> 
     <level2 name="B2" /> 
    </level1> 
    <level1 name="C" /> 
</root> 

कोई मुझे LINQ, सबसे आसान तरीका का उपयोग कर इस परिणाम मुद्रित करने के लिए एक सी # कोड दे सका:
(नोट अतिरिक्त जगह अगर यह एक level2 नोड है)

A 
    A1 
    A2 
B 
    B1 
    B2 
C 

वर्तमान में मैं इस कोड

XDocument xdoc = XDocument.Load("data.xml")); 
var lv1s = from lv1 in xdoc.Descendants("level1") 
      select lv1.Attribute("name").Value; 

foreach (var lv1 in lv1s) 
{ 
    result.AppendLine(lv1); 

    var lv2s = from lv2 in xdoc...??? 
} 
+14

यहाँ यू क्या जरूरत का अच्छा उदाहरण है: [सी # लोड एक्सएमएल (XML को LINQ) XLINQ का उपयोग कर] (http: //www.codearsenal.net/2012/07/c-sharp-load-xml-using-xlinq.html) –

उत्तर

203

इस प्रयास करें मिला है।

void Main() 
{ 
    StringBuilder result = new StringBuilder(); 

    //Load xml 
    XDocument xdoc = XDocument.Load("data.xml"); 

    //Run query 
    var lv1s = from lv1 in xdoc.Descendants("level1") 
       select new { 
        Header = lv1.Attribute("name").Value, 
        Children = lv1.Descendants("level2") 
       }; 

    //Loop through results 
    foreach (var lv1 in lv1s){ 
      result.AppendLine(lv1.Header); 
      foreach(var lv2 in lv1.Children) 
       result.AppendLine("  " + lv2.Attribute("name").Value); 
    } 

    Console.WriteLine(result); 
} 
+23

यह एक प्रकार का "हार्ड कोडेड" दृष्टिकोण दिखता है। – Mohanavel

+2

@bendewey मैं एक समान प्रश्न पूछता हूं, क्या आप इसे यहां देखेंगे, यहां: http://stackoverflow.com/questions/13247449/customize-xml-serialize-with-new-tags-and-attributes-and-root – Saeid

+1

यह सिर्फ मछली पकड़ने के लिए एक विमान वाहक लेने की तरह है। – TomeeNS

8
XDocument xdoc = XDocument.Load("data.xml"); 
var lv1s = xdoc.Root.Descendants("level1"); 
var lvs = lv1s.SelectMany(l=> 
    new string[]{ l.Attribute("name").Value } 
    .Union(
     l.Descendants("level2") 
     .Select(l2=>" " + l2.Attribute("name").Value) 
    ) 
    ); 
foreach (var lv in lvs) 
{ 
    result.AppendLine(lv); 
} 

Ps। आपको इन संस्करणों में से किसी एक पर रूट का उपयोग करना होगा।

+0

क्या यह सभी स्तर 1 के सभी स्तर 2 के बाद प्रिंट नहीं करता है? – sblom

+0

@ एसब्लॉम ओप्स, यह सही है, इसे पोस्ट करने के लिए जो मैंने पोस्ट किया था उसके साथ अपडेट किया (इसके खिलाफ एक परीक्षण चलाया, इसलिए मुझे यकीन है कि यह अब काम करता है :)) – eglasius

21

सादे पुराने foreach छोरों के एक जोड़े को एक साफ समाधान प्रदान करता है:

foreach (XElement level1Element in XElement.Load("data.xml").Elements("level1")) 
{ 
    result.AppendLine(level1Element.Attribute("name").Value); 

    foreach (XElement level2Element in level1Element.Elements("level2")) 
    { 
     result.AppendLine(" " + level2Element.Attribute("name").Value); 
    } 
} 
48

या, यदि आप एक अधिक सामान्य दृष्टिकोण चाहते हैं - करने के लिए "levelN" ऊपर घोंसला बनाने के लिए अर्थात्:

void Main() 
{ 
    XElement rootElement = XElement.Load(@"c:\events\test.xml"); 

    Console.WriteLine(GetOutline(0, rootElement)); 
} 

private string GetOutline(int indentLevel, XElement element) 
{ 
    StringBuilder result = new StringBuilder(); 

    if (element.Attribute("name") != null) 
    { 
     result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value); 
    } 

    foreach (XElement childElement in element.Elements()) 
    { 
     result.Append(GetOutline(indentLevel + 1, childElement)); 
    } 

    return result.ToString(); 
} 
+9

+1 जेनेरिक दृष्टिकोण, सुरुचिपूर्ण रिकर्सन – Askolein

17

यहाँ कुछ पूर्ण काम करने वाले उदाहरण हैं जो @bendewey & @dommer उदाहरणों पर बनाते हैं। मैं हर एक थोड़ा बदलाव करने यह काम करने के लिए प्राप्त करने के लिए जरूरत है, लेकिन इस मामले में एक और LINQ noob उदाहरण काम करने के लिए लग रही है, ये रहा:

//bendewey's example using data.xml from OP 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Linq; 

class loadXMLToLINQ1 
{ 
    static void Main() 
    { 
     //Load xml 
     XDocument xdoc = XDocument.Load(@"c:\\data.xml"); //you'll have to edit your path 

     //Run query 
     var lv1s = from lv1 in xdoc.Descendants("level1") 
      select new 
      { 
       Header = lv1.Attribute("name").Value, 
       Children = lv1.Descendants("level2") 
      }; 

     StringBuilder result = new StringBuilder(); //had to add this to make the result work 
     //Loop through results 
     foreach (var lv1 in lv1s) 
     { 
      result.AppendLine(" " + lv1.Header); 
      foreach(var lv2 in lv1.Children) 
      result.AppendLine(" " + lv2.Attribute("name").Value); 
     } 
     Console.WriteLine(result.ToString()); //added this so you could see the output on the console 
    } 
} 

और अगले:

//Dommer's example, using data.xml from OP 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Linq; 

class loadXMLToLINQ 
{ 
static void Main() 
    { 
     XElement rootElement = XElement.Load(@"c:\\data.xml"); //you'll have to edit your path 
     Console.WriteLine(GetOutline(0, rootElement)); 
    } 

static private string GetOutline(int indentLevel, XElement element) 
    { 
     StringBuilder result = new StringBuilder(); 
     if (element.Attribute("name") != null) 
     { 
      result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value); 
     } 
     foreach (XElement childElement in element.Elements()) 
     { 
      result.Append(GetOutline(indentLevel + 1, childElement)); 
     } 
     return result.ToString(); 
    } 
} 

ये दोनों संकलन & csc.exe संस्करण 4.0.30319.1 का उपयोग कर VS2010 में काम करते हैं और सटीक उसी आउटपुट देते हैं। उम्मीद है कि ये किसी और की मदद करेंगे जो कोड के कामकाजी उदाहरणों की तलाश में है।

संपादित करें: जोड़ा @eglasius 'उदाहरण के रूप में अच्छी तरह के बाद से यह मेरे लिए उपयोगी बन गया:

//@eglasius example, still using data.xml from OP 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Linq; 

class loadXMLToLINQ2 
{ 
    static void Main() 
    { 
     StringBuilder result = new StringBuilder(); //needed for result below 
     XDocument xdoc = XDocument.Load(@"c:\\deg\\data.xml"); //you'll have to edit your path 
     var lv1s = xdoc.Root.Descendants("level1"); 
     var lvs = lv1s.SelectMany(l=> 
      new string[]{ l.Attribute("name").Value } 
      .Union(
       l.Descendants("level2") 
       .Select(l2=>" " + l2.Attribute("name").Value) 
      ) 
      ); 
     foreach (var lv in lvs) 
     { 
      result.AppendLine(lv); 
     } 
     Console.WriteLine(result);//added this so you could see the result 
    } 
} 
संबंधित मुद्दे