I created an XSD file from Visual Studio and can generate a sample XML as well, but my goal is to use this XSD to create an XML file at runtime.
I used XSD.exe to generate a class from my XSD file and then created a program to populate the object from the "class". How can I serialize the object to an XML file?
Both those examples leave the stream open, and XmlFormatter is part of the BizTalk libs - so XmlSerializer would be more appropriate:
using (Stream stream = File.Open(fileName, FileMode.Create))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
serializer.Serialize(stream, MyObject);
stream.Flush();
}
When you have created classes to serialize and deserialize the Xml file using the XSD.exe tool you can write your instances back to files using ..
Serialization! (Archive)
Stream stream = File.Open(filename, FileMode.Create);
XmlFormatter formatter = new XmlFormatter (typeof(XmlObjectToSerialize));
formatter.Serialize(stream, xmlObjectToSerialize);
stream.Flush();
Binary format is binary, use the XML version for XML:
XmlFormatter serializer = new XmlFormatter(typeof(MyObject));
serializer.Serialize(stream, object1);
Related
I received 4 XSD schema files (one is the root, one for header/trailer, one for the base and one for element types)
Passing the root to the xsd.exe, successfully generates the Classes with the proper structure according to the XSD,
we can now assign values to the objects of those classes and populate them, the question is how can we serialise them to XML output keeping the original structure?
We have tried this :
// Serialize all the objects to a single XML file and save it to the output directory
XmlSerializer serializer = new XmlSerializer(objects.GetType());
using (TextWriter writer = new StreamWriter("output.xml"))
{
serializer.Serialize(writer, objects);
}
}
But it's throwing different errors saying:
InnerException = {"Token StartElement in state EndRootElement would result in an invalid XML document. Make sure that the ConformanceLevel setting is set to ConformanceLevel.Fragment or ConformanceLevel.Auto if you want to write an XML fragment. "}
we added setting for the writer:
// Create an XmlWriterSettings object and set the ConformanceLevel to Fragment
var settings = new XmlWriterSettings
{
ConformanceLevel = ConformanceLevel.Fragment
};
// Serialize the data to XML using the serializer and the settings
using (var writer = XmlWriter.Create("example.xml", settings))
{
serializer.Serialize(writer, data);
}
But now it's giving us this error:
{"WriteStartDocument cannot be called on writers created with ConformanceLevel.Fragment."}
Question is, isn't there any straightforward way of serialising the objects to XML without looping through them and have startelement/end element manually inserted to the output XML? doing that is changing the XML structure.
Full code fiddle
XSD files
I am serializing a C# object into an XML document and sending the XML document to a third party vendor. The vendor is telling me that the encoding specification in the document is UTF-16, but the XML document contains UTF-8 content and they can't use it. Here is the code I am using to create the XML file, which runs without error and creates an XML document.
// Instantiate xmlSerializer with my object type.
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
// Instantiate a new stream and pass file location and mode.
Stream stream = new FileStream(#"C:\doc.xml", FileMode.Create);
// Instantiate xmlWriter and pass stream and encoding.
XmlWriter xmlWriter = new XmlTextWriter(stream, Encoding.Unicode);
// Call serialize method and pass xmlWriter and my object.
xmlSerializer.Serialize(xmlWriter, myObject);
// Close writer and stream.
xmlWriter.Close();
stream.Close();
When I run this, the XML Doc shows this on the first line:
<?xml version="1.0" encoding="UTF-16"?>
I've tried changing the Encoding from Encoding.Unicode to Encoding.UTF8 in the XmlTextWriter, but that doesn't change the first line of the XML Doc and it still shows UTF-16.
I also tried using the Serialize method signature that takes 4 parameters (writer, object, namespaces, encoding) and specified UTF8 as the encoding and that didn't change the XML Doc specification either.
I believe all I need to do is change the encoding that shows in the XML Doc to UTF-8 and the third party vendor will be happy. I can't figure out what I am doing wrong.
If I change from Encoding.Unicode to Encoding.UTF8, the file is generated properly. Perhaps you're looking at an old version of your file?
In an unrelated bit, you should use using for deterministic disposal of objects which implement IDisposable:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(MyObject));
using (Stream stream = new FileStream(#".\doc.xml", FileMode.Create))
using (XmlWriter xmlWriter = new XmlTextWriter(stream, Encoding.UTF8))
{
xmlSerializer.Serialize(xmlWriter, myObject);
}
I am serializing an object with the following code, which uses GZip and Xml:
FileStream fs = new FileStream(destinationfolder + "/myFileName.gz",
FileMode.Create, FileAccess.Write);
using (var gz = new GZipStream(fs, CompressionMode.Compress)) {
var serializer = new XmlSerializer(typeof(MyObjectType));
serializer.Serialize(gz, myObject);
}
That works fine, with one single problem: The user can open the .gz file with 7Zip (after setting the file association), but then he can't just doubleclick the shown xml inside the .gz file, since it doesn't have the .xml extension (although the content is actually there, xml formatted and all).
Question is: "How can I serialize XML to a GZipStream so that the .xml extension is saved with the file, inside the .gz archive?" I'm using .NET 4.0.
Thanks for reading.
I have figure out a simple way to solve that. If this way should be considered a hack or a pragmatic and fine solution, is up to each one, I think.
Simply set the GZip filename to myFileName.xml.gz. This actually makes the inner file appear as myFileName.xml (trimming out the .gz extension as before).
I hope this won't break in the future...
All,
I have a list of objects which I have serialized to an XML document using XmlSerializer.
However I would like to wrap the whole result into two tags:
<message>
<!-My Serialized content goes here-->
</message>
Do I need to open it as an XML Document and Add a new root element or is there another way of doing it ?
Rgds,
MK
XmlSerializer writes to an XmlWriter. Write the start tag to the writer first, then serialize, and close your message tag at the end.
Example:
XmlWriter writer = // Your writer
XmlSerializer ser = new XmlSerializer(typeof(DateTime));
writer.WriteStartElement("message");
ser.Serialize(writer,DateTime.Now);
writer.WriteEndElement();
This snippet <!--Please don't delete this--> is part of my xml file. After running this method, the resulting xml file does not contain this snippet anymore <!--Please don't delete this-->. Why is this?
Here's my method:
XmlSerializer serializer = new XmlSerializer(typeof(Settings));
TextWriter writer = new StreamWriter(path);
serializer.Serialize(writer, settings);
writer.Close();
Well, this is quite obvious:
the XmlSerializer will parse the XML file and extract all instances of Settings from it - your comment won't be part of any of those objects
when you write those back out again, only the contents of the Settings objects is written out again
Your comment will fall through the cracks - but I don't see any way you could "save" that comment as long as you're using the XmlSerializer approach.
What you need to do is use the XmlReader / XmlWriter instead:
XmlReader reader = XmlReader.Create("yourfile.xml");
XmlWriter writer = XmlWriter.Create("your-new-file.xml");
while (reader.Read())
{
writer.WriteNode(reader, true);
}
writer.Close();
reader.Close();
This will copy all xml nodes - including comments - to the new file.
<!-- --> signifies a comment in XML. You are writing an object out to XML - objects do not have comments as they get compiled out during compilation.
That is, the Settings object (which is probably a de-serialized form of your .config XML) does not hold comments in memory after de-serializing, so they will not get serialized back either. There is nothing you can do about this behavior of the framework as there is no built in mechanism to de-serialize comments using XmlSerializer.