简体   繁体   中英

Iterate through dataset get child rows

Hoping someone can point me in the right direction with this.

I am trying to iterate through an xml file and get each "table" in the xml file, and get each child rows etc.

I am able to get the rows that are not child rows etc just fine.

Here is an example of the xml structure.

<items>
    <item>
    <id>1</id>
    <row1>abc</row1>
    <row2>abc</row2>
    <needthis>
       <first>John</first>
       <last>John</last>
    </needthis>
    </item>
</items>

This is what I am currently using.

 foreach (DataTable table in ds.Tables)
 {
   foreach (DataRow row in table.Rows)
   {
     foreach (DataColumn column in table.Columns)
     {
        object item = row["id"];
        object item2 = row["row1"];
        //Just to see what is returning
        System.Windows.Forms.MessageBox.Show(item.ToString());
        System.Windows.Forms.MessageBox.Show(item2.ToString());
      } 
    }
  }

What would I need to get the first row and last row of needthis table?

Personally I like Linq to XML for this kind of thing.

//Probably want to use Load if you're using a file
XDocument xDoc = 
        XDocument.Parse (@" 
        <items>
            <item>
            <id>1</id>
            <row1>abc</row1>
            <row2>abc</row2>
            <needthis>
            <first>John</first>
            <last>John</last>
            </needthis>
            </item>
        </items>");

var items = from item in xDoc.Descendants("item") 
            from needThis in item.Descendants("needthis")
            select new 
            {       Id = item.Element("id").Value,
                    Row1 = item.Element("row1").Value,
                    first = needThis.Element("first").Value,
                    last = needThis.Element("last").Value
            };

foreach (var item in items)
{
     Console.WriteLine(item.Id);
     Console.WriteLine(item.Row1);
     Console.WriteLine(item.first);
     Console.WriteLine(item.last);
}

If for some reason you really needed to use datasets you will need to do the following

  1. Not loop over the DataTable collection but just use the item Table
  2. Use GetChildRows using the DataRelation "item_needthis" You can find the data relation name by inspecting the DataSet.Relations Collection


using(MemoryStream stream = new MemoryStream())
{
        StreamWriter writer = new StreamWriter(stream);
        writer.Write(@" 
            <items>
                <item>
                <id>1</id>
                <row1>abc</row1>
                <row2>abc</row2>
                <needthis>
                <first>John</first>
                <last>John</last>
                </needthis>
                </item>
            </items>");
        writer.Flush();
        stream.Position = 0;

    DataSet ds = new DataSet();
    ds.ReadXml(stream);


   DataTable table = ds.Tables["item"];

   foreach (DataRow row in table.Rows)
   {
        Console.WriteLine( row["id"] );
        Console.WriteLine( row["row1"] );
        var ChildRows = row.GetChildRows("item_needthis"); 
        foreach(var ntRow in ChildRows)
        {
            Console.WriteLine( ntRow["first"]);
            Console.WriteLine( ntRow["last"]);
        }
   }


}

You could also use Linq to Datasets

I would use the XElement class instead of DataSets. Then you could read your file even with just this:

XElement root = XElement.Load(...); // or Parse(...)

return root.Elements("item").Select(c => new { id = c.Element("id").Value,
                                               row1 = c.Element("row1").Value,
                                               row2 = c.Element("row2").Value,
                                               needthis = new { first = c.Element("needthis").Element("first").Value,
                                                                last = c.Element("needthis").Element("last").Value } });

Of course I haven't tested this, but you can see the point. It also doesn't have any error handling, and it could be more efficient, but again you can see the gist of how it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM