0

When I read an xml file into a dataset, if the root node has more than one of each child tag, it doesn't create a table for the root node. Why is this? Is there any way to get it to generate the root table without modifying the xml?

static void Main(string[] args) {
    var ds =Load(@"<root>
      <Stores>Lambton Quay</Stores>
      <Stores>Willis Street</Stores>
    </root>");
    var ds2 = Load(@"<root>
      <t>1</t>
      <Stores>Lambton Quay</Stores>
      <Stores>Willis Street</Stores>
    </root>");
    Console.WriteLine("ds table count: {0}", ds.Tables.Count); //1 <- expecting 2
    Console.WriteLine("ds2 table count: {0}", ds2.Tables.Count); //2
    Console.ReadKey();
}
static DataSet Load(string xml) {
    var xd = new XmlDocument();
    xd.LoadXml(xml);
    var ds = new DataSet();
    ds.ReadXml(new XmlNodeReader(xd));
    return ds;
}

Edit:

To be clear I want to know why the DataSet ds doesn't have a root table while ds2 does.

Someone made the decisions:

  1. if only 1 node exists with a given tag name under a given parent tag, it becomes a column in the table named by the parent tag.
  2. if more than one such node exists, it becomes a table on its own
  3. if all child nodes appear more than once and the parent node is the document root, the parent table does not get created

What is the reason for #3?

Bill Barry
  • 3,423
  • 2
  • 24
  • 22

1 Answers1

-1

The first XML example doesn't create a "root" table in the dataset because there would be no rows or columns created in a table with that name.

In the second example, try adding a second <t> element. You will still get two tables but they will be named "t" and "Stores" (instead of "root" and "Stores"). Another test is to add another different element to the second example (say <r>1</r>). In this case you will still have two tables "root" and "Stores" but now the "root" table will have 1 row with 2 columns (column "r" and column "t").

When the parser sees two elements with the same name it will create a table for that element and each instance of the element will be a new row in the table. When the parser sees multiple single elements under a node, it will create a table using the name of the parent node as the table name and each single element under the parent node will be a column in the table.

pmartin
  • 2,731
  • 1
  • 25
  • 30
  • There would be an Id column created. The root node does contain information: that the Stores are related to each other at the same level. I understand that this is how it works, I want to understand why this is the way it works. – Bill Barry Sep 30 '11 at 14:55
  • The reason it works that way is because the design fulfilled the majority of use cases for XML serialization to a dataset. That's not to say that the way you want it to work is invalid - it's just not the norm. If you really need it to work a specific way - you can always "roll your own" serialization methods. – pmartin Sep 30 '11 at 15:30