none
DataTable.ReadXml

    Question

  • Hi There,
    I am trying to read some xml into a DataTable. The xml fragmaent is simply:
    <REP>
    	<ID>3</ID>
    	<Name>Andrew</Name>
    	<RegionID>3</RegionID>
    	<Sales>23880</Sales>
    </REP> 
    Using ASP.NET, the code which I have written is:

            protected void GridViewEmployees_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                if (e.Row.RowType == DataControlRowType.DataRow)
                {                
                    DataTable tblXml = new DataTable();
                    String firstLine = "&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;";
                    String frag = Server.HtmlDecode(firstLine + e.Row.Cells[3].Text);
                    TextReader readXML = new StringReader(frag);                
                    tblXml.ReadXml(readXML);
                       ...
                }
             }


    The error message that I am getting with the call to ReadXml is "DataTable does not support schema inference from Xml."
    I have tried reading in a schema which I created using xsd, but it still gives the same error. Is there something that I am missing?
    Sunday, September 20, 2009 8:41 AM

Answers

  • It seems that you still need to have a DataSet tag, even though there is no DataSet. At least when I tried it, that's what worked for me. And you don't need that "xml version" and all that stuff either.

    So, what you'll want to do, is something along these lines (it works for me):

    String frag = "<NewDataSet>" + e.Row.Cells[3].Text + "</NewDataSet>";
    StringReader sr = new StringReader(frag);
    tblXml.ReadXml(sr);

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Marked as answer by drogers101 Monday, November 09, 2009 1:01 PM
    Monday, November 09, 2009 12:56 AM

All replies

  • I believe this is the correct behaviour. If nothing else by judging by the exception.

    What I believe happens here is that you are trying to read xml into a datatable which has no schema.
    And this can't be done. In your code you are only creating the table, but no schema or columns etc. are set, so it fails.

    What you need to do is to set the correct schema for the datatable before loading the XML, or to setup the columns etc correctly.
    As long as you just new up a DataTable and then call ReadXml on it, it will fail as long as the XML doesn't contain the schema.

    Hopefully the short code example below shows this:

                try
                {
                    DataTable dt = new DataTable("DemoTable");
                    dt.Columns.Add(new DataColumn("id", typeof(int)));
                    dt.Columns.Add(new DataColumn("name", typeof(string)));
    
                    dt.Rows.Add(new object[] { 1, "Mike" });
                    dt.Rows.Add(new object[] { 2, "John" });
    
                    dt.WriteXml(@"C:\Temp\TableXml.xml");
                    dt.WriteXmlSchema(@"C:\Temp\TableSchemaXml.xml");
                    dt.WriteXml(@"C:\Temp\TableAndSchemaXml.xml", XmlWriteMode.WriteSchema);
    
                    DataTable dt2 = new DataTable();
                    // This fails with "DataTable does not support schema inference from Xml"
                    //dt2.ReadXml(@"C:\Temp\TableXml.xml");
                    
                    // This works, schema first then data
                    dt2.ReadXmlSchema(@"C:\Temp\TableSchemaXml.xml");
                    dt2.ReadXml(@"C:\Temp\TableXml.xml");
    
                    // or schema and data
                    //dt2.ReadXml(@"C:\Temp\TableAndSchemaXml.xml");
    
                    //// or create the tables columns etc.
                    DataTable dt3 = new DataTable("DemoTable");
                    dt3.Columns.Add(new DataColumn("id", typeof(int)));
                    dt3.Columns.Add(new DataColumn("name", typeof(string)));
                    dt3.ReadXml(@"C:\Temp\TableXml.xml");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
    HTH
    //Michael
    This posting is provided "AS IS" with no warranties.
    Monday, September 21, 2009 1:31 PM
  • The Error is fine.... Because the Data Table is not having the Schema.

    Better create the columns in the table and try to import.

    To add the columns in the table use :

    DataTable.Columns.Add(New DataColumn());

    Refer :

    http://msdn.microsoft.com/en-us/library/hfx3s9wd.aspx;

    http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/1b8c331e-55b7-4cf4-a8ec-c0b24e2a7b3e

    Tuesday, September 22, 2009 1:12 PM
  • I did read in a schema. It was not included in my code snippet, but I mentioned it in the last sentence of my post.

    I create an xsd file using xsd. I then read in that schema file using tblXml.ReadXmlSchema. I read in the schema before I made the call to ReadXml().

    This is why I am puzzled. Do you need to manually create the columns if you use a schema? Because that is the only thing I haven't done. That is, manually create columns.
    Wednesday, September 23, 2009 8:41 AM
  • The error is simple. When you instantiate a new instance of DataTable, the TableName should match the root node of the Xml.

    DataTable table = new DataTable("REP");
    .......do the rest as you had it.........
    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    • Marked as answer by Yichun_Feng Friday, September 25, 2009 2:21 AM
    • Unmarked as answer by drogers101 Saturday, October 03, 2009 11:57 PM
    Wednesday, September 23, 2009 6:27 PM
  • Hi John,

    I'm nearly there, but not quite. Now, no null reference is thrown when the DataTable tries to read in the TextReader.
    But, I'm left with an empty grid.

    This works fine when I just use a DataSet, rather than a DataTable. But I want to understand why it won't work with w DataTable.
    The code now is:
                if (e.Row.RowType == DataControlRowType.DataRow)
                {
                    DataTable dtXml = new DataTable("REP");
                    String firstLine = "&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;";
                    String frag = Server.HtmlDecode(firstLine + e.Row.Cells[3].Text);
                    TextReader readXML = new StringReader(frag);                
                    dtXml.ReadXmlSchema(@"O:\XmlInGridView\XmlInGridView\frag.xsd");
                    dtXml.ReadXml(readXML);
                    GridView GridViewEmployeeDetails = e.Row.FindControl("GridViewEmployeeDetails") as GridView;
                    GridViewEmployeeDetails.DataSource = dtXml;
                    GridViewEmployeeDetails.DataBind();                
                }
    Thursday, September 24, 2009 1:41 PM
  • Do you have an Xml file that has been saved somewhere? If so, then you do not need the String firstLine or frag. Simply select the Xml file. In other words, do this:

    DataTable table = new DataTable("REP");
    String s = File.ReadAllText("1.xml");
    table.ReadXmlSchema(new StringReader(s));
    table.ReadXml(new StringReader(s));

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    • Marked as answer by Yichun_Feng Friday, September 25, 2009 2:21 AM
    • Unmarked as answer by drogers101 Saturday, October 03, 2009 11:57 PM
    Thursday, September 24, 2009 4:06 PM
  • The Xml (frag) is coming from an Xml field in a SQL Server database. There is no Xml declaration in that field. That is whay I added the firstLine.
    The schema is an xsd file which I manually created using the VS 2008 tool xsd.

    As far as I can tell, it has enough information to populate the DataTable.
    Friday, September 25, 2009 7:25 AM
  • You do not have to "manually" write out the Xml declaration. If you are using an XmlTextWriter for example, use the WriteStartDocument() method, and it will start your Xml with that declaration.

    If you are using XmlDocument, use the CreateXmlDeclaration method.
    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Friday, September 25, 2009 9:46 PM
  • I'm not using anything from the Xml libraries. I'm just using a StringReader to read in the Xml from the Text field of a Label (ASP.NET). I tried playing around with the Xml classes, but in this context, it was square peg, round hole.

    If I don't include the firstLine, I get an XmlException "Root element is missing." But I don't think the firstLine is the problem here, as it works fine when I use a Dataset, rather than a DataTable.

    The DataTable has the Xml and the schema. I cannot see why it won't just work, as the DataSet does. I'm complying with the API. You read in the schema. Then the Xml. As far as the API goes, it is satisfied.
    Monday, September 28, 2009 10:07 AM
  • I thought I would bump this thread to see if anyone had any ideas to solve the problem.
    Saturday, November 07, 2009 7:38 AM
  • It seems that you still need to have a DataSet tag, even though there is no DataSet. At least when I tried it, that's what worked for me. And you don't need that "xml version" and all that stuff either.

    So, what you'll want to do, is something along these lines (it works for me):

    String frag = "<NewDataSet>" + e.Row.Cells[3].Text + "</NewDataSet>";
    StringReader sr = new StringReader(frag);
    tblXml.ReadXml(sr);

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Marked as answer by drogers101 Monday, November 09, 2009 1:01 PM
    Monday, November 09, 2009 12:56 AM
  • Hey thanks Bonnie. That does work. It seems a little wierd, because the xsd file that I am reading in has in its root element <xs:schema id="NewDataSet" 

    But I am satisfied. I was really just curious why the DataTable had the same counterpart methods for reading in Xml and XmlSchmas as the DataSet, but didn't seem to work. Now I know that I can just slip in a "<NewDataSet>" root element and all will be well.

    Thanks again!
    Monday, November 09, 2009 1:01 PM
  • Hey, no problem ... glad to help. =0)

    Yeah, it does seem weird, but whatever works, right? ;0)
    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Tuesday, November 10, 2009 5:18 AM