Xml back to Dataset?

C

Carl

Hi

I've tried lots of different ways to get this example to work, but nothing
seems to happen.

I have a Dataset in a winform. I take one record in the dataset and convert
it to Xml with the WriteXml method. This works fine.

Then I export it to Word, do a minor change to it (using the Xml-tools for
Word), and hook up the BeforeSave event. This also works fine.

When the code in the event starts to execute, I get the Xml-code back, I can
see that it is changed when I inspect it. Good.

Now, to get it into a dataset, and update it to the backend db seems
virtually impossible. In the code below, two of all of my trials are present
(one is commented out). Exceptions are never raised, it just does not do
anything! I would be very happy if someone could point out what I'm doing
wrong!

Generate the Xml to send to Word:

private void GenerateXML_Click(object sender, EventArgs e)
{
//testDataSet tds = new testDataSet();

DataTable dt = documentTableAdapter.GetDocumentById(1);
DataSet ds = new DataSet();
ds.Tables.Add(dt);

StringWriter sw = new StringWriter();
ds.WriteXml(sw, XmlWriteMode.DiffGram);
xmlDoc = sw.ToString();
if (! File.Exists(xmlFileName))
{
ds.WriteXml(xmlDoc, XmlWriteMode.DiffGram);
}

if (!File.Exists(xmlSchemaName))
{
ds.WriteXmlSchema(xmlSchemaName);
}
}

Send it to Word:

private void btSendToWord_Click(object sender, EventArgs e)
{
Word.ApplicationClass wordApp = new Word.ApplicationClass();
wordApp.Visible = true;
Word.Document doc = wordApp.Documents.Add(ref missing, ref
missing, ref missing, ref missing);

Object aliasObj = "XmlTestSchema";
Object namespaceUriObj = "http://www.w3.org/2001/XMLSchema";
Word.XMLNamespace schema =
wordApp.XMLNamespaces.Add("c:\\Temp\\XmlTest\\XmlTestSchema.xsd", ref
namespaceUriObj, ref aliasObj, false);
Object obj = doc;
schema.AttachToDocument(ref obj);

Word.Range range = doc.Range(ref missing, ref missing);
range.InsertXML(xmlDoc, ref missing);

wordApp.DocumentBeforeSave += new
Microsoft.Office.Interop.Word.ApplicationEvents4_DocumentBeforeSaveEventHandler(wordApp_DocumentBeforeSave);
}

Try to get it back, this is probably where the problem is:

void
wordApp_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc, ref
bool SaveAsUI, ref bool Cancel)
{
string xmlReturn = Doc.Range(ref missing, ref
missing).get_XML(true);
System.Diagnostics.Debug.Write(xmlReturn);

//DataSet ds = new DataSet();
//ds.ReadXml(new StringReader(xmlReturn),
XmlReadMode.InferSchema);

testDataSet.ReadXml(new StringReader(xmlReturn),
XmlReadMode.DiffGram);
//testDataSet.Merge(ds, true, MissingSchemaAction.AddWithKey);

documentTableAdapter.Update(testDataSet);
}

regards

Carl
 
S

Sahil Malik [MVP]

Carl,

How many datatables does your dataset have? Also the changes that you are
making - what table are they in? (First table? Second table?)

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
----------------------------------------------------------------------------
 
C

Carl

Thanks for Your answer.

The dataset has only one table, it looks like this when saved to Xml:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<Document>
<id>1</id>
<Type>aType</Type>
<Name>aName</Name>
<Date>2005-06-03T00:00:00.0000000+02:00</Date>
<Text>some text</Text>
</Document>
</NewDataSet>

The only change I make (in Word) is to the Type value (change to some other
text). It all comes back to VS in good shape, looking like this:

<?xml version="1.0" standalone="no"?>
<NewDataSet>
<Document>
<id>1</id>
<Type>Changed value here</Type>
<Name>aName</Name>
<Date>2005-06-03T00:00:00.0000000+02:00</Date>
<Text>some text</Text>
</Document>
</NewDataSet>

regards

Carl
 
R

Rogas69

Well there is also a change in 'standalone' attribute - maybe it has
something to do with the problem? The other guess would be that there is an
unicode preamble before <?xml tag and it may cause problems. Check memory
view of the string.

Peter
 
S

Sahil Malik [MVP]

Well the data adapter will act upon the dataset based upon the various row
states. Per your code, the rowstates should not change - which is why it
isn't working.

How to fix this?

Load the resultant XML in a different dataset, merge the two datasets (must
have schema in the datasets for this to work), and while merging specify
PreserveChanges = true (it is the second parameter of the second overload).

If you do that, then the new change will affect the rowstate and the
datadapter will pick it. :)

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
 
C

Carl

If the standalone attribute is "no" means that a DTD or schema is needed. I
tried ReadXmlSchema, which did not raise any exceptions, and then read the
xml. It made no difference. I also looked for an preamble, but there was
nothing. The first data in both directions is the "<".

Carl
 
C

Carl

Wow, this is the closest I've been so far!

The changed data gets inserted as a new row instead of updating the one I
originally send though. Any hints about that?

regards

Carl
 
R

Rogas69

Maybe instead of creating new dataset after loading it from word try to do
'dummy' update like
Tables[0].Rows[0]["Name"] = Tables[0].Rows[0]["Name"];

regards

peter
 
S

Sahil Malik [MVP]

Carl,

So I take it that this result is after your attempt to merge?

Well, the answer is simply that the rowstate is "Added" not "Modified", so
the InsertCommand is getting executed, and not the UpdateCommand. And the
rowstate is incorrect because of missing schema information in your
datasets. You need to specify schema information to the datasets, because
Merge uses that information to merge properly.

How to fix it?

You have to run in debug mode and verify that the post merge dataset and the
rowstates inside of it are really what you expect. I suspect what is
happening over here is that the schema information is not provided. Just for
kicks, change the dataset to a strongly typed dataset that accurately mimics
the underlying data source/table structures - and first verify that the
merge is working properly. If it is, then you're in good shape :), data
should get updated, not inserted.

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
 
S

Sahil Malik [MVP]

Yes, but what if there are both inserted, and updated rows, which one do you
update as shown below? IMO this is a logically incorrect solution.

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
 
S

Sahil Malik [MVP]

Can't guarantee that :). Atleast your code shouldn't rely on that
especially when you do have an alternate proper method available.

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
 
R

Rogas69

Of course you are generally right :) but Carl seems be wanting to update not
insert new records using Word :). Simplest solutions that meet requirements
are the best IMHO :). Of course well commented. :)

Peter
 
S

Sahil Malik [MVP]

Generally right, but not always :). Thanks for your inputs.

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
----------------------------------------------------------------------------
---------------

Rogas69 said:
Of course you are generally right :) but Carl seems be wanting to update not
insert new records using Word :). Simplest solutions that meet requirements
are the best IMHO :). Of course well commented. :)

Peter

Sahil Malik said:
Can't guarantee that :). Atleast your code shouldn't rely on that
especially when you do have an alternate proper method available.

- Sahil Malik [MVP]
Upcoming ADO.NET 2.0 book - http://tinyurl.com/9bync
--------------------------------------------------------------------------
--
 
C

Cor Ligthert

Carl,

The easiest way to test this is just past it in a notepad. Write it as xml.
Create a form with a datagrid and than use this code.
\\\
DataSet ds = new DataSet();
ds.ReadXml(@"C:\Test1\Carl.XML");
this.dataGrid1.DataSource = ds.Tables[0].DefaultView;
///

It showed me a nice filled datagrid.

I hope this helps,

Cor
 
C

Carl

I'm using a strong dataset, and exports the schema, and reloads it again at
update-time. When I inspect the "tds" dataset in the BeforeSave event, it is
"Added" just like you expected. Should I change this property by code (to
"Changed"), or is there another solution?

private void GenerateXML_Click(object sender, EventArgs e)
{
DataTable dt = documentTableAdapter.GetDocumentById(1);
testDataSet ds = new testDataSet();
ds.Tables.RemoveAt(0);
ds.Tables.Add(dt);

StringWriter sw = new StringWriter();
ds.WriteXml(sw, XmlWriteMode.IgnoreSchema);
xmlDoc = sw.ToString();
if (! File.Exists(xmlFileName))
{
ds.WriteXml(xmlFileName, XmlWriteMode.IgnoreSchema);
}

if (!File.Exists(xmlSchemaName))
{
ds.WriteXmlSchema(xmlSchemaName);
}
}


void
wordApp_DocumentBeforeSave(Microsoft.Office.Interop.Word.Document Doc, ref
bool SaveAsUI, ref bool Cancel)
{
string xmlReturn = Doc.Range(ref missing, ref
missing).get_XML(true);
System.Diagnostics.Debug.Write(xmlReturn);

testDataSet tds = new testDataSet();
tds.ReadXmlSchema("C:\\temp\\xmltest\\xmltestschema.xsd");
tds.ReadXml(new StringReader(xmlReturn), XmlReadMode.Auto);

//testDataSet.ReadXmlSchema("C:\\temp\\xmltest\\xmltestschema.xsd");
testDataSet.Merge(tds, true);

documentTableAdapter.Update(testDataSet);

documentTableAdapter.Fill(testDataSet.Document);
}

Carl
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top