save DataSet to XML

  • Thread starter Thread starter jez
  • Start date Start date
J

jez

Perhaps a rather easy question for most of you but I'm stuck on it.

1) I've been trying for the past couple of days to save my dataset to
an XML file. I used to be able to save it without problem by using the
following method :

CustomersDS.WriteXml("deliveredCustomers.xml",
XmlWriteMode.WriteSchema);

now I get the following error : "System.Data.DataSet.WriteXml(string,
System.Data.XmlWriteMode)' is inaccessible due to its protection
level" - what does that mean? My dataset is initialised as private, I
changed it to public but still get the same problem.

2) I've also been trying to save directly to an XML file without going
through a DataSet (should save time!) by using the streamwriter and
the innerXml method. I've created a rather simple form with a couple
of textboxes that I want to save to XML when I click on a button.

This is what the code looks like :

private void buildXmlDoc() {
XmlDocument xmlDoc = new XmlDocument();
XmlNode deliveredCustomersNode;
XmlNode nameNode;
XmlNode emailNode;

xmlDoc.Load("customersDelivered.xml");
deliveredCustomersNode = xmlDoc.CreateElement("delivered");
xmlDoc.DocumentElement.AppendChild(deliveredCustomersNode);

nameNode = xmlDoc.CreateElement("Name");
nameNode.InnerText = listBox1.SelectedValue.ToString();
deliveredCustomersNode.AppendChild(nameNode);

emailNode = xmlDoc.CreateElement("Email");
emailNode.InnerText = textBoxEmail.Text;
deliveredCustomersNode.AppendChild(emailNode);

//create a FileStream obj so we can save the XML file
FileStream strmSaveToFile = new FileStream("customersDelivered.xml",
FileMode.OpenOrCreate,FileAccess.Write);

//instantiating a DataWriter obj so we can write the XML file
to disk
StreamWriter wrDataWriter = new StreamWriter(strmSaveToFile);

wrDataWriter.Write(xmlDoc.InnerXml);
wrDataWriter.Close();

MessageBox.Show("XML file saved!");

textBoxAddress.DataBindings.Clear();
textBoxPhone.DataBindings.Clear();
textBoxEmail.DataBindings.Clear();
textBoxCountry.DataBindings.Clear();

textBoxAddress.Text="";
textBoxPhone.Text="";
textBoxEmail.Text="";
textBoxCountry.Text="";

listBox1.SelectedIndex=0;

DataSet _CustomersDS = new DataSet("Customers");
_CustomersDS.ReadXml("customersDelivered.xml");

bindControls();
}

This method however doesn't seem to work.
Does the deliveredCustomers.xml file need to exist before I can use
this method ?

Is there any way I can add/append data to the end of the xml file ?

Thanks a lot !

jez
 
Does your project have a reference to System.Xml? This is required to use
the ReadXml and WriteXml DataSet methods. Select the Project menu > Add
Reference... and select System.Xml and click "Select" and Ok.

Peter
 
Peter,

I have just added a reference to System.Xml yet I still can't save it to an
xml file. I alread had a reference to System.Xml at the beginning of my
program (using System.Xml;) - is it not the same?

I also put a breakpoint at the beginning of the buildXmlDoc() method to see
where exactly it gets stuck and seems to be at the point where it loads the
xml document : << xmlDoc.Load("customersDelivered.xml"); >>. When I instruct
VS.NET to go to the next step it jumps to the catch clause.

When I take the try/catch clause out I get the following error (at the
xmlDoc.Load line) :
<<
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in
System.Xml.dll

Additional information: FileNotFoundException
Does this mean that the xml file has to exist before I can save to it ?#

thanks

jez
 
Peter,

I have just added a reference to System.Xml yet I still can't save it to an
xml file. I alread had a reference to System.Xml at the beginning of my
program (using System.Xml;) - is it not the same?

I also put a breakpoint at the beginning of the buildXmlDoc() method to see
where exactly it gets stuck and seems to be at the point where it loads the
xml document : << xmlDoc.Load("customersDelivered.xml"); >>. When I instruct
VS.NET to go to the next step it jumps to the catch clause.

When I take the try/catch clause out I get the following error (at the
xmlDoc.Load line) :
<<
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in
System.Xml.dll

Additional information: FileNotFoundException
Does this mean that the xml file has to exist before I can save to it ?

thanks

jez
 
If i understand the description correctly, you're saying that the following
line of code fails
with System.IO.FileNotFoundException:
xmlDoc.Load("customersDelivered.xml");

In order to *load* the file, it must exist. Does it? Note that Pocket PC
has no notion of current directory, so it's looking for
"customersDelivered.xml" at the root of the filesystem.

-- Ray
 
That's right!

The file doesn't actually exist at all. This is what I'd like(love)
that method to do :

* if the file exists just append it
* if the file doesn't exist create a file and add the text fields to
it

basically, instead of saving everything in a dataset each time is
there a possibility to save(or change) text fields straight away to an
xml file ?

By changing I mean the following : If I read an xml file into a
dataset and I then make some ammendment to a textfield and I then want
to save it back to that xml file, is there a way for the CF to change
the bits that have been manually changed by the user in that xml file
?

after saving those bits to the xml file I reload the xml file in a
dataset to get the most up to date data from the xml file.

I hope that doesn't sound to complicated.. It's just that I read about
the innerXml method and it sounded perfect.

thanks a lot
jez
 
FileMode.OpenOrCreate is fine when writing, but I don't know of a way to
*read* from a non-existent file. Before doing the xmlDoc.Load(fileName),
you'll need to ensure the file already exists, or else catch the
FileNotFoundException. Once you do that, your example code ought to be
fine.

I haven't worked with xmlDoc.InnerXml, don't know how the performance would
be. But I'd suggest against reloading the DataSet from the xml file every
time you change the data. DataSet.ReadXml is *slow*... it's much improved
in Windows Mobile 2003 (.NET CF development team, thanks!), but still slow.
For example, an app I'm currently developing uses a typed DataSet, typical
data files have 100-500 elements... ReadXml takes several seconds, but
WriteXml
is fast enough (less than 0.5 second) to use at appropriate times without
interrupting the user's workflow.

-- Ray
 
Ray,

Okay so I need the xml file to exist before I load (sounds kind of
logical I guess). What method should I use then to write to an xml
file from a dataset so that at a later time I can "edit" fields in a
dataset and write back to that same xml file ?

here's a step-by-step proc I think I should follow :
1) have an xml file ready on the PPC with data in it (and in a format
the dataset can read)
2) load that xml file into a dataset
3) change the dataset
4) write the dataset back to the xml file and change in the xml file
any fields that have been changed in the dataset. (for example if
phone number was changed from "1888xxx" to "1555xxx" change it in the
appropriate field in the xml file")

-- I think (thought?) the only way to do that was using the innerXml
method. Can you correct me if I'm wrong?

Basically all I'm looking to do is get data from an XML file into a
dataset, change it (or add data to the dataset) and write it back to
the xml file. Obviously i'd prefer not having to write the entire xml
file each time but only the parts that changed.

As for the speed issues - should I not be worried about leaving data
in a dataset for too long ? what happens if the battery's empty ? I
thought it might be more interesting to save it to an xml file each
time (about 40 times/day max) to ensure we have data consistency.

thanks,
jez
 
Jez,

While very flexible, XML format got some disadvantages as well.

It's hard and slow to parse, has very big storage space overhead, and
there's no good/easy way to update or append data in XML files.
You also can not retrieve some data from XML without parsing entire file.

You could not just insert your data into XML or add few records to the end
of XML file as it will result in malformed XML structure rendering file
useless.
Sure, you can take care of keeping XML file structure, but it's neither
easy nor fast and simply not worth it.
So, you have to overwrite your file every time you need to change or append
some data.
DataSet.ReadXml() and DataSet.WriteXml() will do this for you.

If it's not acceptable, XML is not for you. It's great for exchanging data
between various platforms, but not really good as data storage.
Use some other storage, like fixed size binary structures which are easy to
append or update; or CSV file which is easy to append to, but not very easy
to update.
Alternatively, switch to a database (e.g. SQL Server CE). It will take care
of appending and updating for you.

Best regards,

Ilya


This posting is provided "AS IS" with no warranties, and confers no rights.



--------------------
From: (e-mail address removed) (jez)
Newsgroups: microsoft.public.dotnet.framework.compactframework
Subject: Re: save DataSet to XML
Date: 12 Dec 2003 05:34:43 -0800
Organization: http://groups.google.com
Lines: 99
Message-ID: <[email protected]>
References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
 
Back
Top