I want to save the complete result of a FOR XML SQL Query to a file.
My SQL Query looks something like this:
SELECT * FROM Customer FOR XML RAW
in my code, I now want to execute this query against an SQL Server and read the complete XML result and save it to disk.
My code looks like this:
using (XmlReader xmlResultReader = command.ExecuteXmlReader()) //command is my SqlCommand
using (MemoryStream resultFile = new MemoryStream())
using (StreamWriter writer = new StreamWriter(resultFile, Encoding.UTF8))
{
while (xmlResultReader.Read())
{
writer.WriteLine(xmlResultReader.ReadOuterXml());
}
//write stream to file
}
But when I run this, not the complete result of the query gets saved to the MemoryStream. The result is truncated in the middle of a <row /> element in the resulting XML. So not even the returned XML is valid.
I also tried writing the result with an XmlWriter using this code:
xmlWriter.WriteNode(xmlResultReader, false);
but this showed the same result.
So now my question is: How can I get the complete XML result of the query from the XmlReader returned by ExecuteXmlReader()?
I think, DataSet is bet suited for such requirement.Save file to disk is time taking ,you cannot keep connection for so long using SqlDataReader or XMLdataReader.
Load Result set in Dataset.
Loop throgh dataset
Perform validation whether xml file is genuine.
Save file to disk one by one.
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(yourXMLString);
xdoc.Save("C:\myfilename.xml");
Related
I have an App which communicate to a MySQL database via webservice. The webservice serves the app with XML. Now I want to replace the MySQL database with a SQLite database. To avoid changing all logic I only need to get an XML format back from my SQLite database. To increase the level of problem, I have to read data from more than one table. Details of App: For each table I have the structure of my tables in class stored and this is the code I use currently which is not working:
XmlSerializer xs = new XmlSerializer(typeof(myTableClass));
var sRe = new myTableClass();
using (XmlWriter writer = XmlWriter.Create(sww))
{
xs.Serialize(writer, sRe);
var buf = sww.ToString();
return buf;
}
I expect a string of my XML in the variable buf, but when I run this code it just jump out on the first row. What is wrong in my code?
I am using http://www.thescarms.com/dotnet/XSLT.aspx to Convert comma delimited data (CSV) to XML using XSLT template.
It uses the foll. 2 lines of .NET code:
XSLT.Load(mstrInputXSLTFile, resolver);
XSLT.Transform(mstrInputCSVFile, mstrOutputXMLFile, resolver);
I am looking for a way in which I can use the string contents (contents of the XSLT, CSV file) instead of files in above 2 methods.. Any help will be usefull.
I am planning to implement this logic in a WCF webservice which will receive the csv string. If there is no workaround then I will have to create temp files based on the values of csv and xsl received. Process the conversion of csv to xml on the server and return the xml output to the client. Then delete the files created above.
If you want to load the input from a string then create an XmlReader over a StringReader over your string e.g.
XslCompiledTransform proc = new XslCompiledTransform();
using (StringReader sr = new StringReader(stringVar))
{
using (XmlReader xr = XmlReader.Create(sr))
{
proc.Load(xr);
}
}
There is no suitable method in XslTransform which does what you want.
However, you could write your own extensions methods (I would call them Parse..), which take content as string, create files in the temporary directory, and load/transform them by the suitable methods.
I have a series of... pseudo-xml files. What I mean by this, is they are almost XML files, but they are missing the xml declaration and a root node. e.g. conceptually it may look like this:
<a>info</a>
<b>info2</b>
What I want to do is load it into an XmlDocument object, e.g something similar to this:
XmlDocument xml = new XmlDocument();
using (StreamReader file = new StreamReader(File.Open(#"file.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
xml.Load(file);
}
This is throwing errors, most likely due to the ill formatted pseudo-xml file. I need to somehow handle adding in a root node before it hits the Load. I don't want to modify the actual file, or have to save anything to disk (e.g. a new temp file). I'm stuck on this, any suggestions?
XmlDocument has also a LoadXml() method that parses an Xml string. You can load your file content into a string, add the declaration and call LoadXml().
Of course, when you are using long files, this can be very memory consuming, pay attention to that.
you could try this
var xmlString = file.ReadToEnd();
xmlString = "<root>" + xmlString + "</root>";
xml.LoadXml(xmlString);
I'd like to transform a string that contains an xml using a XSLT, it's for a Colombian company, so I have the following code (don't try to understand it):
string xmlTFDNode = #<tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital TimbreFiscalDigital.xsd" selloCFD="tOSe+Ex/wvn33YlGwtfmrJwQ31Crd7lI9VcH63TGjHfxk5vfb3q9uSbDUGk9TXvo70ydOpikRVw+9B2Six0m bu3PjoPpO909oAYITrRyomdeUGJ4vmA2/12L86EJLWpU7vIt4cL8HpkEw7TOFhSdpzb/890+jP+C1adBsHU1VHc=" FechaTimbrado="2010-03-06T20:40:10" UUID="ad662d33-6934-459c-a128-bdf0393e0f44" noCertificadoSAT="30001000000100000801" version="1.0" selloSAT="j5bSpqM3w0+shGtImqOwqqy6+d659O78ckfstu5vTSFa+2CVMj6Awfr18x4yMLGBwk6ruYbjBlVURodEIl6n JIhTTUtYQV1cbRDG9kvvhaNAakxqaSOnOx79nHxqFPRVoqh10CsjocS9PZkSM2jz1uwLgaF0knf1g8pjDkLYwlk="/>
and I have a XLST stored on the server named InvoiceTFD.xslt
This is the XSLT file
I want to create a method to return a string with the data transformed, it shoud look like this (that's what the XSLT does):
||1.0|ad662d33-6934-459c-a128-bdf0393e0f44|2001-12-
17T09:30:47Z|iYyIk1MtEPzTxY3h57kYJnEXNae9lvLMgAq3jGMePsDtEOF6XLWbrV2GL/
2TX00vP2+YsPN+5UmyRdzMLZGEfESiNQF9fotNbtA487dWnCf5pUu0ikVpgHvpY7YoA4
lB1D/JWc+zntkgW+Ig49WnlKyXi0LOlBOVuxckDb7EAx4=|12345678901234 567890||
The problem I is that the XslTransform.Transform method creates a new file, and I don't want to write a file
Recapitulating, I just want to take a string, transform it using a XSLT file I have, and return a string with the transformation without creating files on the server, that's it!
I believe it's not that hard, but I'm new in .NET so I really don't know how to do it :(
Thanks in advance and have a great day guys !!
You can write to a memory stream:
MemoryStream oStream = new MemoryStream()
oXslt.Transform(new XPathDocument(new XmlNodeReader(oXml)), null, oStream );
oStream.Position = 0
StreamReader oReader = new StreamReader(oStream);
string output = oReader.ReadToEnd();
BTW, use XPathDocument and XslCompiledTransform. They are much faster than XslTransform and XmlDocument. Even if you use an XmlDocument to create the xml, covert it to an XPathDocument for the transform.
Transform method can take Stream outputStream parameter. You can create StringWriter and pass it as output stream.
Use XslCompiledTransform instead of XslTransform. Use method: XslCompiledTransform.Transform, save result to OutputStream.
As I see, your XSLT is version 2.0. Neither of them support XSLT 2.0.
Is there anything built in to determine if an XML file is valid. One way would be to read the entire content and verify if the string represents valid XML content. Even then, how to determine if string contains valid XML data.
Create an XmlReader around a StringReader with the XML and read through the reader:
using (var reader = XmlReader.Create(something))
while(reader.Read())
;
If you don't get any exceptions, the XML is well-formed.
Unlike XDocument or XmlDocument, this will not hold an entire DOM tree in memory, so it will run quickly even on extremely large XML files.
You can try to load the XML into XML document and catch the exception.
Here is the sample code:
var doc = new XmlDocument();
try {
doc.LoadXml(content);
} catch (XmlException e) {
// put code here that should be executed when the XML is not valid.
}
Hope it helps.
Have a look at this question:
How to check for valid xml in string input before calling .LoadXml()