Reading XML Into A Dataset

April 8th, 2008
by psykoprogrammer

One of the coolest things about the .NET platform is the power how it manipulates data, and, more importantly, how those smart peeps at Microsoft have devised a very nice API for manipulating your data in a consistent set of interfaces, mostly regardless of the data source. In this little tutorial I’m going to talk about how we can take XML data that represents some set of data, and bring it into a DataSet object to manipulate like a table with rows.

So, for this example, we will be using an XML file that looks like this.

  1. <products>
  2. <product>
  3. <id>1</id>
  4. <name><![CDATA[Super Widget 1]]></name>
  5. <description><![CDATA[The Super Widget 1 is the first and simplest widget in our product line. Perfect for beginners.]]></description>
  6. <category><![CDATA[Widgets]]></category>
  7. <price>19.99</price>
  8. </product>
  9. <product>
  10. <id>2</id>
  11. <name><![CDATA[Super Widget 2]]></name>
  12. <description><![CDATA[The Super Widget 2 is the bigger widget in our product line. Use when more power is needed.]]></description>
  13. <category><![CDATA[Widgets]]></category>
  14. <price>29.99</price>
  15. </product>
  16. </products>

As you can see we have a basic XML representation of a set of records that represent product data. And in this case, we sell Widgets. In this set of data we are selling two widgets, and track the following fields: id, name, description, category, and price.

Now, .NET has lots of powerful XML capabilities. With forward reading cursors and XPath you can usually get to what you want. However it can be desirable to treat an XML document, especially one formatted like this, as a DataSet. Let’s look at how that can be done.

First you will need to make sure you have included the proper namespaces to do this. We are going to need Xml and IO.

  1. using System.Xml;
  2. using System.IO;

Once we have these assemblies in place the steps to get this XML into a DataSet as as follows:

  1. Read the XML file into an XmlDocument structure.
  2. Get the XML document object into a byte array.
  3. Create a memory stream reader against the byte array.
  4. Read the data into a DataSet object.
  5. Close the memory stream reader.

Let’s look at how this code comes out.

  1. XmlDocument xmlDoc = new XmlDocument();
  2. DataSet result = new DataSet();
  3. MemoryStream reader;
  4. byte[] xmlBuffer;
  5.  
  6. xmlDoc.LoadXml(File.ReadAllText("yourFile.xml"));
  7.  
  8. xmlBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(xmlDoc.OuterXml);
  9. reader = new MemoryStream(xmlBuffer);
  10.  
  11. result.ReadXml(reader, XmlReadMode.Auto);
  12. reader.Close();

The first step is to bring the raw XML string data into an XmlDocument object. This is done using the LoadXml method. Notice how we are calling the method ReadAllText from the static class Fileto get the XML file into a string to pass to the LoadXml function.

After this we get the ASCII bytes of the XML document into a byte array. This is necessary for the MemoryStream reader. In this case we instantiate a new MemoryStream class called reader that will be used to read the bytes from the byte array xmlBuffer.

Then we use the method ReadXml from the DataSet class to unserialize the XML data to a DataSet object. In this example please note we are passing XmlReadMode.Auto as the second parameters. This tells the ReadXml to determine infer schema for the XML when translating to a DataSet object. For this case that is sufficient, though you can get more sophisticated with XML schema to dictate data types and organization.

Once we’ve done all this we need to close our stream reader. Now, how do we use it? Well, there are a lot of things that can be done, and what you do with this DataSet is certainly dependent upon what you are trying to accomplish. For a simple example let’s pretend that you have a combo box on a form and wish to populate it with a list of your products.

For this I would keep a variable representing the DataTable, populate the combo box, and when you need to get the selected product’s ID you can reference the DataTable. Here’s an example that assumes you have a variable declared at the form’s class level called tblProducts, and will populate the combo box, which is named cboProducts.

  1. XmlDocument xmlDoc = new XmlDocument();
  2. DataSet result = new DataSet();
  3. MemoryStream reader;
  4. byte[] xmlBuffer;
  5.  
  6. xmlDoc.LoadXml(File.ReadAllText("products.xml"));
  7.  
  8. xmlBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(xmlDoc.OuterXml);
  9. reader = new MemoryStream(xmlBuffer);
  10.  
  11. result.ReadXml(reader, XmlReadMode.Auto);
  12. reader.Close();
  13.  
  14. //————————————————–
  15. // There is only one "table" in the dataset. This is
  16. // our products table. Populate the products in our
  17. // combo box.
  18. //————————————————–
  19. tblProducts = result.Tables[0];
  20.  
  21. foreach (DataRow row in tblProducts.Rows)
  22. {
  23. cboProducts.Items.Add(row["name"].ToString());
  24. }
  25.  
  26. cboProducts.SelectedIndex = 0;

In the code above, much is the same as the example we already talked about. The big difference here is we get the first (and only) table from the DataSet. We then iterate over all of the DataRow items in the Rows member of the table and add the product name to the combo box.

Now, lets assume you have a button on this form that, when clicked, will display a message box with the product information.

  1. int selectedIndex = cboProducts.SelectedIndex;
  2. DataRow product = tblProducts.Rows[selectedIndex];
  3. StringBuilder message = new StringBuilder();
  4.  
  5. message.Append(String.Format("Product: {0} ({1})\r\n", product["name"].ToString(), product["id"].ToString()));
  6. message.Append(String.Format("Description: {0}\r\n", product["description"].ToString()));
  7. message.Append(String.Format("Category: {0}\r\n", product["category"].ToString()));
  8. message.Append(String.Format("Price: ${0}\r\n", product["price"].ToString()));
  9.  
  10. MessageBox.Show(message.ToString(), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);

Basically here we get the selected index from the combo box, and with that information retrieve the DataRow from the tblProducts DataTable we created previously. After this we construct a string message using the StringBuilder class and display it in a message box.

And there you have it. How to, and an example of, using XML data in a DataSet object. I have attached a ZIP file in the list below of the sample code for your compiling goodness, as well as a good bird’s eye article on DataSets, DataTables, and the like. Happy coding!

Comments (1)

One Response to “Reading XML Into A Dataset”

  1. Adam->Blog(); » Tutorial: .NET XML Into A DataSet Says:

    [...] the data like it came from a database. See the Software Development section, or go straight to it here. Cheers, and happy [...]

Leave a Reply

You must be logged in to post a comment.