none
datatables and dataset.readxml() problems RRS feed

  • Question

  • I'm running into inconsistencies with loading certain XML into a dataset. What happens, is when I normally load xml into a dataset with dataset.readxml(), it creates datatables for every element with child elements and creates relations among them. my problem is that when I read in xml with a specific element/object in it, it does not contain the root node as a table and only contains the child tables of the root table. the code I am working with requires that the root table be present.  The code/xml looks similar to this:

    XML:
    <response>
        <info>
            <code>blah</code>
            <desc>desc</desc>
        </info>
        <info>
            <code>blah</code>
            <desc>desc</desc>
        </info>
        <usercontext>
            <username>name</username>
            <usermenu>menu</usermenu>
            <timestamp>timestampgoeshere</timestamp>
        </usercontext>
    </response>

    and the code gets that xml into an xmlreader and uses dataset.readxml to read it out to the dataset. When I have the usercontext element in there, it only has datatables for usercontext and info. But when I take it out, it properly has a datatable for response and info with a relationship between them. Ideally there should be a relationship between each of the child tables (info/usercontext) and the response table. Any suggestions?

    Edited for formatting

    Monday, August 7, 2006 5:03 AM

Answers

  • Ok, I fully understand the root of the problem I believe. Described here:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconinferringtables.asp
    is how schema gets inferred if you end up doing that when reading xml with no schema defined (such as xml that is serialized from an object like in my case).
    What is happening is that my xml that I need to read is being inferred in the first example of "Elements with Child Elements" with the root node being translated as the dataset. What I want to happen is to force the dataset to always infer in the way described in the second example of "Elements with Child Elements" where the dataset is just named "NewDataSet" and the top element is its own table. This is to make it work with the existing code already in place I am working with.

    I figured out how to force it to infer the correct schema.  its a hack but it works for now.

                DataSet ds = new DataSet();
                // Read the XML document into the DataSet.
                ds.ReadXml(ms);

                // if the dataset is not named newdataset, the schema was inferred wrong; wrap the xml and re-read it into a fresh dataset
                if (ds.DataSetName != "NewDataSet")
                {
                    String xml = string.Format("<NewDataSet>{0}</NewDataSet>", ds.GetXml());
                    ds = new DataSet();
                    ds.ReadXml(new StringReader(xml));
                }       
    Monday, August 7, 2006 5:30 PM

All replies

  • I really struggled hard to read your post. I suggest you use capital letters for 'I' and first letters of sentences. It really helps the reader!

    If the code that reads the xml is something like:

    Dim dataset as new dataset
    dataset.readxml(mystream)

    then this requires the xml to contain it's schema also. So it should have been created by something like this: dataset.writexml("myfile.xml", XmlWriteMode.WriteSchema).

    Else, you should create the schema before loading the file:
    Dim dataset as new dataset
    dataset.tables.add("mytable1")
    dataset.tables.add("mytable2")
    dataset.relations.add(.......)
    ...
    ...
    dataset.readxml(mystream)

    Monday, August 7, 2006 11:31 AM
  • Sorry for the formatting of the post, i'm used to autocorrect capitalizing my I's and such :).

    I'm actually generating the xml from a serialized object and loading that xml into a brand new dataset, but it seems the end result is the same.  I can't really explicitly define the tables and relations in the code itself as it is a very abstract module and is extended by multiple other modules.  I believe I already attempted to do something like this:

    Dataset ds = new Dataset();
    ds.ReadXml(myXmlReader, XmlWriteMode.ReadSchema);

    but it didnt seem to work in the specific case that is giving me trouble.  I'll play around with it a little more and see what other information I can provide.
    Monday, August 7, 2006 12:47 PM
  • XmlWriteMode.ReadSchema does not work simply because your xml file does not include schema! You should use IncludeSchema as mentioned on my previous port when creating your xml. I you don't include schema in xml and you don't provide it by code then there is nothing that relates your data together.
    Monday, August 7, 2006 12:51 PM
  • Hmm...the thing is though that even though my xml doesnt seem to have a schema around it, it works as I expect it to when its formed a certain way (i.e., the usercontext element is not there).

    With further testing, I believe i have found the issue.  When I read the xml into the newly created dataset it infers a schema, and within that schema is this:

    <xs:element name="response" msdata:IsDataSet="true">

    For some reason it sets that IsDataSet attribute to true when the usercontext is present, which makes that element into the dataset and not the root table as I want it to be.  Is there a way to force it to set that to false when it reads the xml?  If not I suppose I'll have to read the xml, get the schema and if that is set improperly then change the xml and re-read the changed schema and xml back into the dataset.  Any ideas?

    Monday, August 7, 2006 2:33 PM
  • Ok, I fully understand the root of the problem I believe. Described here:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconinferringtables.asp
    is how schema gets inferred if you end up doing that when reading xml with no schema defined (such as xml that is serialized from an object like in my case).
    What is happening is that my xml that I need to read is being inferred in the first example of "Elements with Child Elements" with the root node being translated as the dataset. What I want to happen is to force the dataset to always infer in the way described in the second example of "Elements with Child Elements" where the dataset is just named "NewDataSet" and the top element is its own table. This is to make it work with the existing code already in place I am working with.

    I figured out how to force it to infer the correct schema.  its a hack but it works for now.

                DataSet ds = new DataSet();
                // Read the XML document into the DataSet.
                ds.ReadXml(ms);

                // if the dataset is not named newdataset, the schema was inferred wrong; wrap the xml and re-read it into a fresh dataset
                if (ds.DataSetName != "NewDataSet")
                {
                    String xml = string.Format("<NewDataSet>{0}</NewDataSet>", ds.GetXml());
                    ds = new DataSet();
                    ds.ReadXml(new StringReader(xml));
                }       
    Monday, August 7, 2006 5:30 PM