Problem reading an XML string without first writing to disk

T

Thirsty Traveler

I have a dataset that is returned from a sql server select that contains
metadata and a cached dataset saved in an xml column. I would like to
recover the dataset for use in generating a crystal pdf file. the
rptds.ReadXml method can accept either a string file indicating a filename
or a stream. the row["xmldata"].ToString() is the saved dataset. If I use
this directly it throws an error because it is data and not a filename. I
have a workaround seen below that first writes the xml to a temporary
diskfile and then reads it back in in the rptds.ReadXml statement. Although
this works, it is definitely kludgy... there must be a better way.



Any suggestions?



Sample Code:



public static void CreatePDF()
{
DataSet batchds = TestDAL.GetAllBatches();


foreach (DataRow row in batchds.Tables[0].Rows)
{
StreamWriter swtst = new StreamWriter(@"Test.xml", false,
Encoding.Default);
swtst.Write(row["xmldata"].ToString());
swtst.Close();


DataSet rptds = new DataSet();
rptds.ReadXml(@"Test.xml");


TestRpt rpt = new TestRpt ();
rpt.SetDataSource(rptds);


rpt.ExportToDisk(ExportFormatType.PortableDocFormat,
row["FileName"].ToString());
}
}
 
L

Larry Lard

Thirsty said:
I have a dataset that is returned from a sql server select that contains
metadata and a cached dataset saved in an xml column. I would like to
recover the dataset for use in generating a crystal pdf file. the
rptds.ReadXml method can accept either a string file indicating a filename
or a stream. the row["xmldata"].ToString() is the saved dataset. If I use
this directly it throws an error because it is data and not a filename. I
have a workaround seen below that first writes the xml to a temporary
diskfile and then reads it back in in the rptds.ReadXml statement. Although
this works, it is definitely kludgy... there must be a better way.

You said the answer yourself: rptds.ReadXml wants a file or a stream.
If we are not to give it a file, we must give it a stream. What kind of
stream can we make from data that is in memory already? A MemoryStream.
How do we make a MemoryStream? From an array of byte. How do we make an
array of byte from a string? With Encoding.GetBytes.

The details are left as an exercise for the reader.

Incidentally, I would be interested to know if anyone can find a method
that (unlike this one) doesn't involve using twice as much memory as
the string takes. Can we derive from Stream and create our own
StringStream, perhaps?
 
T

Thirsty Traveler

Thanks... I was playing with MemoryStream but unable to get it to work...
Encoding.GetBytes was my missing link.

Larry Lard said:
Thirsty said:
I have a dataset that is returned from a sql server select that contains
metadata and a cached dataset saved in an xml column. I would like to
recover the dataset for use in generating a crystal pdf file. the
rptds.ReadXml method can accept either a string file indicating a
filename
or a stream. the row["xmldata"].ToString() is the saved dataset. If I use
this directly it throws an error because it is data and not a filename. I
have a workaround seen below that first writes the xml to a temporary
diskfile and then reads it back in in the rptds.ReadXml statement.
Although
this works, it is definitely kludgy... there must be a better way.

You said the answer yourself: rptds.ReadXml wants a file or a stream.
If we are not to give it a file, we must give it a stream. What kind of
stream can we make from data that is in memory already? A MemoryStream.
How do we make a MemoryStream? From an array of byte. How do we make an
array of byte from a string? With Encoding.GetBytes.

The details are left as an exercise for the reader.

Incidentally, I would be interested to know if anyone can find a method
that (unlike this one) doesn't involve using twice as much memory as
the string takes. Can we derive from Stream and create our own
StringStream, perhaps?
 
J

Jon Skeet [C# MVP]

Larry Lard said:
You said the answer yourself: rptds.ReadXml wants a file or a stream.

That's not strictly true though. It wants a file, a stream, a
TextReader or an XmlReader. TextReader is what we want here -
StringReader, specifically.
 
T

Thirsty Traveler

The following code works without having to write/read from disk:

public static void CreatePDF()
{
DataSet batchds = TestDAL.GetAllBatches();

foreach (DataRow row in batchds.Tables[0].Rows)
{
DataSet rptds = new DataSet();
byte[] b = Encoding.UTF8.GetBytes(row["Data"].ToString());
MemoryStream ms = new MemoryStream(b);

rptds.ReadXml(ms);

TestRpt rpt = new TestRpt ();
rpt.SetDataSource(rptds);

rpt.ExportToDisk(ExportFormatType.PortableDocFormat,
row["FileName"].ToString());
}
}
 
J

Jon Skeet [C# MVP]

Thirsty Traveler said:
The following code works without having to write/read from disk:

Yes, but it does create a copy of the data. Why not use create a
StringReader, as I suggested?

StringReader reader = new StringReader(row["Data"].ToString());
rptds.ReadXml(reader);
 
L

Larry Lard

Jon said:
That's not strictly true though. It wants a file, a stream, a
TextReader or an XmlReader. TextReader is what we want here -
StringReader, specifically.

That's what I get for trusting the info on the support call, I suppose
:)
 
T

Thirsty Traveler

Awesome... this final touch rendered the solution simple and elegant.

Thanks.

Jon Skeet said:
Thirsty Traveler said:
The following code works without having to write/read from disk:

Yes, but it does create a copy of the data. Why not use create a
StringReader, as I suggested?

StringReader reader = new StringReader(row["Data"].ToString());
rptds.ReadXml(reader);
 

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