Lost XML file declaration using DataSet.WriteXml(Stream) - c#

I had a Dataset with some data in it. When I tried to write this DataSet into a file, everything was OK. But When I tried to write it into a MemoryStream, the XML file declaration was lost.
The code looks like:
DataSet dSet = new DataSet();
//load schema, fill data in
dSet.WriteXML("testFile.xml");
MemoryStream stream = new MemoryStream();
dSet.WriteXML(stream);
stream.Seek(0,SeekOrigin.Begin);
When I opened file testFile.xml, I got:
<?xml version="1.0" standalone="yes"?>
//balabala
But When I open the stream with StreamReader, I only got:
//balabala
Somebody said I can insert XML file declaration in my stream manually. It works but seems so ugly. Do you know why it dropped the first line and any more simple solution?

It wasn't dropped. Simply not included. Though it is highly recommend the xml declaration is not a required element of the xml specification.
http://msdn.microsoft.com/en-us/library/ms256048(VS.85).aspx
You can use XmlWriter.WriteStartDocument to include the xml declaration in the stream like so:
MemoryStream stream = new MemoryStream();
var writer = XmlWriter.Create(stream);
writer.WriteStartDocument(true);
dSet.WriteXML(stream);

I try your solution with DataTable and don't work correctly.
using (MemoryStream stream = new MemoryStream()) {
using (XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8)) {
writer.WriteStartDocument(); //<?xml version="1.0" encoding="utf-8"?>
writer.WriteRaw("\r\n"); //endline
writer.Flush(); //Write immediately the stream
dTable.WriteXml(stream);
}
}

If you disassemble the 2.0 code you'll see that the WriteXml method that takes a file name explictly writes out the declaration (XmlWriter.WriteStartDocument) but the WriteXml methods that take a stream or writer do not.

Related

Flat xml file c#

I'm wrting xml file with UTF-8 (without Bom) encoding as follow:
xmldecl.Encoding = "UTF-8";
dataDoc.InsertBefore(xmldecl, root);//dataDoc is XmlDocument object
using (var writer = new XmlTextWriter(targetPath, new UTF8Encoding(false)))
{
dataDoc.Save(writer);
}
My "problem" is the file is saved in one line instead of xml formatting,
I.e if i have the following xml:
<ElementA>
<ElementB/>
</ElementA>
With my code the xml file will be:
<ElementA><ElementB/></ElementA>
Instead of xml format.
How can i solve it?
*I'm try to open the file with Notepad++
Thanks.
XmlTextWriter has a property Formatting to define the way the output is written:
using (var writer = new XmlTextWriter(targetPath, new UTF8Encoding(false)))
{
writer.Formatting = Formatting.Indented;
dataDoc.Save(writer);
}

Changing Word Document XML

What I am doing is trying to change the value of a Microsoft Office Word documents XML and save it as a new file. I know that there are SDK's that I could use to make this easier but the project I am tasked with maintaining is doing things this way and I was told I had to as well.
I have a basic test document with two placeholders mapped to the following XML:
<root>
<element>
Fubar
</element>
<second>
This is the second placeholder
</second>
</root>
In my test project I have the following:
string strRelRoot = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
//the word template
byte[] buffer = File.ReadAllBytes("dev.docx");
MemoryStream stream = new MemoryStream(buffer, true);
Package package = Package.Open(stream, FileMode.Open, FileAccess.ReadWrite);
//get the document relationship
PackageRelationshipCollection pkgrcOfficeDocument = package.GetRelationshipsByType(strRelRoot);
//iterate through relationship
foreach (PackageRelationship pkgr in pkgrcOfficeDocument)
{
if (pkgr.SourceUri.OriginalString == "/")
{
//uri for the custom xml
Uri uriData = new Uri("/customXML/item1.xml", UriKind.Relative);
//delete the existing xml if it exists
if (package.PartExists(uriData))
{
// Delete template "/customXML/item1.xml" part
package.DeletePart(uriData);
}
PackagePart pkgprtData = package.CreatePart(uriData, "application/xml");
//hard coded test data
string xml = #"<root>
<element>
Changed
</element>
<second>
The second placeholder changed
</second>
</root>";
Stream fromStream = pkgprtData.GetStream();
//write the string
fromStream.Write(Encoding.UTF8.GetBytes(xml),0,xml.Length);
//destination file
Stream dest = File.Create("test.docx");
//write to the destination file
for (int a = fromStream.ReadByte(); a != -1; a = fromStream.ReadByte())
{
dest.WriteByte((byte)a);
}
}
}
What is happening right now is the file test.docx is being created but it is a blank document. I'm not sure why this is happening. Any suggestions anyone could offer on this approach and/or what I am doing incorrectly would be very much appreciated. Thanks much!
After your fromStream.Write call, the stream pointer is positioned after the data you've just written. So your first call to fromStream.ReadByte is already at the end of the stream, and you read (and write) nothing.
You need to either Seek to the beginning of the stream after writing (if the stream returned by the package supports seeking), or close fromStream (to ensure the data you've written is flushed) and reopen it for reading.
fromStream.Seek(0L, SeekOrigin.Begin);

Deserialization error in XML document(1,1)

I have an XML file that I deserialize, the funny part is the XML file is the was serialized
using the following code:
enter code here
var serializer = new XmlSerializer(typeof(CommonMessage));
var writer = new StreamWriter("OutPut.txt");
serializer.Serialize(writer, commonMessage);
writer.Close();
And i m trying to deserialized it again to check if the output match the input.
anyhow here is my code to deserialize:
var serializer = new XmlSerializer(typeof(CommonMessage));
var reader = new StringReader(InputFileName);
CommonMessage commonMessage = (CommonMessage)serializer.Deserialize(reader);
Replace StringReader with StreamReader and it will work fine. StringReader reads value from the string (which is file name in your case).
I just had the same error message but different error source. In case someone has the same problem like me. I chopped off the very first char of my xml string by splitting strings. And the xml string got corrupted:
"?xml version="1.0" encoding="utf-16"?> ..." // my error
"<?xml version="1.0" encoding="utf-16"?> ..." // correct
(1,1) means basically first char of the first line is incorrect and the string can't be deserialized.
include in your CommonMessage class the XmlRoot element tag with your xmlroot eg:[XmlRoot("UIIVerificationResponse")]
You should disable the order mark in the StreamWriter constructor like this:
UTF8Encoding(false)
Full sample:
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream, new UTF8Encoding(false)))
{
xmlSerializer.Serialize(writer, objectToSerialize, ns);
return Encoding.UTF8.GetString(stream.ToArray());
}

XML.Save file writing mystery

What I'm trying to do here is see whether the element exists in the xml document, if it does exist then i want to modify the inner text of it. if it doesnt exist i would like to create it and also create the appropriate inner text for it. However, when it an element does exist and i try to change it's inner text to something shorter than it was the whole xml files writing seems to shift.
My code:
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(path);
XmlNodeList felement = xmldoc.GetElementsByTagName(Element);
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
if (felement.Count == 0)
{
XmlElement elmRoot = xmldoc.DocumentElement;
XmlElement xmlele = xmldoc.CreateElement(Element);
xmlele.AppendChild(xmldoc.CreateTextNode(data));
elmRoot.AppendChild(xmlele);
xmldoc.Save(fs);
}
else
{
felement[0].InnerText = data;
xmldoc.Save(fs);
}
fs.Close();
XML File before modifying with a shorter inner text:
<?xml version="1.0" encoding="utf-8"?>
<MyXMLFile>
<Source>C:\Users\Dacto\Desktop\</Source>
<Destination>C:\Program Files\Adobe</Destination>
</MyXMLFile>
After shorter inner text:
<?xml version="1.0" encoding="utf-8"?>
<MyXMLFile>
<Source>C:\Users\Dacto\Desktop\Napster</Source>
<Destination>C:\Users</Destination>
</MyXMLFile>/MyXMLFile>
See the "extra" /MyXMLFile> what's going on??
Since the output isn't valid XML then it's unlikely that XmlDocument.Save produced the entire content of the file. Given this, I'd suspect that when creating the FileStream you should supply a different parameter rather than FileMode.Open - FileMode.Create will ensure that the file is truncated before being written to - currently it's being overwritten, leaving the old content in place if the new file isn't large enough to cover it.
The problem is with they way that you are writing out the file, not with the xml. If you try something like,
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
byte[] info = new UTF8Encoding(true).GetBytes("AAAAA");
fs.Write(info, 0, info.Length);
You should see:
AAAAA version="1.0" encoding="utf-8"?>
<MyXMLFile>
<Source>C:\Users\Dacto\Desktop\</Source>
<Destination>C:\Program Files\Adobe</Destination>
</MyXMLFile>
Instead of FileMode.Open, you want FileMode.Create, so that the file gets truncated before you write to it if it exists already.
Another option that you have to save the XmlDocument is through the use of an XmlWriter instead of a FileStream.
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(path);
XmlNodeList felement = xmldoc.GetElementsByTagName(Element);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using (XmlWriter wr = XmlWriter.Create(path), settings))
{
if (felement.Count == 0)
{
XmlElement elmRoot = xmldoc.DocumentElement;
XmlElement xmlele = xmldoc.CreateElement(Element);
xmlele.AppendChild(xmldoc.CreateTextNode(data));
elmRoot.AppendChild(xmlele);
xmldoc.Save(wr);
}
else
{
felement[0].InnerText = data;
xmldoc.Save(wr);
}
}
Also, if you continue with your original FileStream method, then I would recommend wrapping it in a using statement like I have done above with the XmlWriter and if you do, then you can get rid of the fs.Close() statement.

Dataset -> XML Document - Load DataSet into an XML Document - C#.Net

I'm trying to read a dataset as xml and load it into an XML Document.
XmlDocument contractHistoryXMLSchemaDoc = new XmlDocument();
using (MemoryStream ms = new MemoryStream())
{
//XmlWriterSettings xmlWSettings = new XmlWriterSettings();
//xmlWSettings.ConformanceLevel = ConformanceLevel.Auto;
using (XmlWriter xmlW = XmlWriter.Create(ms))
{
xmlW.WriteStartDocument();
dsContract.WriteXmlSchema(xmlW);
xmlW.WriteEndDocument();
xmlW.Close();
using (XmlReader xmlR = XmlReader.Create(ms))
{
contractHistoryXMLSchemaDoc.Load(xmlR);
}
}
}
But I'm getting the error - "Root Element Missing".
Any ideas?
Update
When i do xmlR.ReadInnerXML() it is empty. Does anyone know why?
NLV
A few things about the original code:
You don't need to call the write start and end document methods: DataSet.WriteXmlSchema produces a complete, well-formed xsd.
After writing the schema, the stream is positioned at its end, so there's nothing for the XmlReader to read when you call XmlDocument.Load.
So the main thing is that you need to reset the position of the MemoryStream using Seek. You can also simplify the whole method quite a bit: you don't need the XmlReader or writer. The following works for me:
XmlDocument xd = new XmlDocument();
using(MemoryStream ms = new MemoryStream())
{
dsContract.WriteXmlSchema(ms);
// Reset the position to the start of the stream
ms.Seek(0, SeekOrigin.Begin);
xd.Load(ms);
}
XmlDocument contractHistoryXMLSchemaDoc = new XmlDocument();
using (MemoryStream ms = new MemoryStream())
{
dsContract.WriteXml(ms);
ms.Seek(0, SeekOrigin.Begin);
using(XmlReader xmlR = XmlReader.Create(ms))
{
contractHistoryXMLSchemaDoc.Load(xmlR);
}
}
All you really need to do is to call contractHistoryXMLSchemaDoc.Save(ms). That will put the xml into the MemoryStream.
XmlDocument contractHistoryXMLSchemaDoc = new XmlDocument();
using (MemoryStream ms = new MemoryStream())
{
contractHistoryXMLSchemaDoc.Save(ms);
ms.Flush();
}
Here you go.
If from the naming convention of your variables, (not though the question you asked, which appears to change...), you need to load the XML scema of the data set into the XML document that you named with schema, below is the code to load schema of the dataset into an XMLDocument.
I want the schema of the dataset in a separate XML document. – NLV Apr 19 '10 at 12:01
Answer:
XmlDocument contractHistoryXMLSchemaDoc = new XmlDocument();
using (MemoryStream ms = new MemoryStream())
{
dsContract.WriteXmlSchema(ms);
ms.Seek(0, SeekOrigin.Begin);
contractHistoryXMLSchemaDoc.Load(ms);
}
If you are looking for how to load the dataset table data into an XML document (note I removed the word Schema from the XMLDocument variable name)
Your Question:
Sorry, i dont get you. I need to get the xml of that dataset into an xml document. – NLV Apr 19 '10 at 11:56
Answer:
XmlDocument contractHistoryXMLDoc = new XmlDocument();
using (MemoryStream ms = new MemoryStream())
{
dsContract.WriteXml(ms,XmlWriteMode.IgnoreSchema);
ms.Seek(0, SeekOrigin.Begin);
contractHistoryXMLDoc.Load(ms);
}
If you want the Schema and data set in separate documents, the code is above.
If you want just the schema or just the data in and xml document, use the above bit of code that pertains to your question.
If you want both the XML Schema and the Data in the same XMLDocument, then use this code.
XmlDocument contractHistoryXMLDoc = new XmlDocument();
using (MemoryStream ms = new MemoryStream())
{
dsContract.WriteXml(ms,XmlWriteMode.WriteSchema);
ms.Seek(0, SeekOrigin.Begin);
contractHistoryXMLDoc.Load(ms);
}
Your Question:
But I'm getting the error - "Root Element Missing".
Any ideas?
Update
When i do xmlR.ReadInnerXML() it is empty. Does anyone know why?
NLV
Answer:
There are underlying issues in your code in the way you think it is working, which means it is not really creating the XMLSchema and XmlData (dsContract), which is why you are seeing a blank XMLDocument.
It would probably help you to fully explain what you wish, and then not reply to everyone using partial sentences of which are misunderstood and your having to keep replying with more partial sentences.

Categories

Resources