How read use an ADO.NET DataSet to read XML files designed with nested attributes?
I am working on a project that is XML driven and I am using ADO.NET DataSet functionality to make reading the XML easier. However, I ran into a problem that really just a lack of knowledge on my part.
Problem
So I have DataSet created using an XML. The XML is using Nested attributes. And I just need to know how to loop properly through the DataSet Tables and their columns.
I have the following XML.
<?xml version="1.0" encoding="utf-8" ?> <plugin PluginName="TestName" GroupName="Operating System Settings" Type="Single"> <title>Plugin 1</title> <startTime>1:57:47 PM 2/16/2010</startTime> <endTime>1:58:03 PM 2/16/2010</endTime> <description>Runs the TestName process to determine something.</description> <section SectionName="Section1"> <field FieldName="Field Name"> <value Operand="EQ">Some Correct Setting1</value> <actionPlugin Name="" Type="Link" URL=""> <executable>SomeAction1.exe</executable> <parameters>Param1 Param2</parameters> </actionPlugin> </field> <field FieldName="Field2"> <value Operand="RG">900</value> <warningLevel>10%</warningLevel> <errorLevel>20%</errorLevel> <actionPlugin Name="ActionPlugin1" Type="Link" URL="http://www.somesite.tld/some/path/file.htm" /> </field> </section> <section SectionName="Section2"> <field FieldName="Field1"> <value Operand="EQ">Some Correct Setting2</value> <actionPlugin Name="" Type="Link" URL=""> <executable>SomeAction2.exe</executable> <parameters>Param1 Param2</parameters> </actionPlugin> </field> <field FieldName="Field2"> <value Operand="RG">900</value> <warningLevel>10%</warningLevel> <errorLevel>20%</errorLevel> <actionPlugin Name="ActionPlugin1" Type="Link" URL="http://www.somesite.tld/some/path/file.htm" /> </field> </section> <section SectionName="Section3"> <field FieldName="Field1"> <value Operand="EQ">Some Correct Setting3</value> <actionPlugin Name="" Type="Link" URL=""> <executable>SomeAction3ds.exe</executable> <parameters>Param1 Param2</parameters> </actionPlugin> </field> <field FieldName="Field2"> <value Operand="RG">900</value> <warningLevel>10%</warningLevel> <errorLevel>20%</errorLevel> <actionPlugin Name="ActionPlugin1" Type="Link" URL="http://www.somesite.tld/some/path/file.htm" /> </field> </section> </plugin>
So the DataSet is created with these tables (this is copied from the debugger):
– List Count = 5 System.Collections.ArrayList
+ [0] {Plugin} object {System.Data.DataTable}
+ [1] {Section} object {System.Data.DataTable}
+ [2] {Field} object {System.Data.DataTable}
+ [3] {Value} object {System.Data.DataTable}
+ [4] {ActionPlugin} object {System.Data.DataTable}
Table [1] {Section} has 3 rows.
Table [2] {Field} has 6 rows.
So the data looks like this:
Sections Table
Row 1
Row 2
Row 3Fields Table
Row 1
Row 2
Row 3
Row 4
Row 5
Row 6
But I need to read it as follows:
Sections Table Row 1 Fields Table Row 1 Row 2 Row 2 Fields Table Row 3 Row 4 Row 3 Fields Table Row 5 Row 6
So I had the code below, but for each Section Row it would loop through all six field rows, which is not what I intend.
string mFullPathToXML = "C:\My.xml"; DataSet ds; ds.ReadXml(mFullPathToXML); foreach (DataRow SectionRow in ds.Tables["Section"].Rows) { foreach(DataRow FieldRow in ds.Tables["Field"].Rows) { // Looping through all rows, not just those that pertain to the section. // How to get only the two rows that belong to each Section row here? } }
Solution
Well, I set out on a journey to figure this out. In a few search engines I use search phrases like:
DataSet XML Nested
DataSet XML Nested Relation
DataSet DataTable XML Nested Row
DataSet DataTable XML Nested Row
A lot of documentation on Microsoft’s site to XMLs and DataSets showed up, but nothing describing this problem/solution.
I am happy to say that with help from the MSDN Forums, the solution was found. Please read my post here:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/2d115ba6-49be-4a5c-bf92-054626109f50
So the solutions is to use the Section_Id assigned to each row in the Sections table inside the Field table’s Select() function as shown:
foreach (DataRow sectionRow in ds.Tables["Section"].Rows) { string sectionId = sectionRow["Section_Id"].ToString(); Console.WriteLine("Section: {0}", sectionRow["SectionName"]); foreach (DataRow fieldRow in ds.Tables["Field"].Select("Section_Id = " + sectionId)) { foreach (object item in fieldRow.ItemArray) { // Do something here } } }
This solution works for me.