LINQ XML पढ़ने के लिए


194

मुझे यह XML फ़ाइल मिली:

<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 का उपयोग करके कोई मुझे C # कोड दे सकता है, इस परिणाम को प्रिंट करने का सबसे सरल तरीका है:
(यदि 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
यहाँ क्या यू की जरूरत का अच्छा उदाहरण है: C # लोड XML का उपयोग कर XLINQ (LINQ to XML)

जवाबों:


224

इसे इस्तेमाल करे।

using System.Xml.Linq;

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

3
@bendewey मैं एक ऐसा ही सवाल पूछता हूं, क्या आप इसे यहां देख पाएंगे: stackoverflow.com/questions/13247449/…
Saeid

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

53

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

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

23

सादे पुराने 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);
    }
}

19

यहाँ पूर्ण कार्य करने वाले कुछ उदाहरण हैं जो @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();
    }
}

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

EDIT: @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
    }
}

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। आपको इसका उपयोग करना होगा। इनमें से किसी भी संस्करण पर क्लिक करें।


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

@sblom ऊप्स, यह सही है, मैंने इसे पोस्ट करने के उद्देश्य से अपडेट किया (इसके खिलाफ एक परीक्षण चलाया, इसलिए मुझे यकीन है कि यह अब काम करता है :))
इगलासियस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.