I have a class like this:
public class Response
{
public String AdditionalData = "";
public Boolean Success = false;
public int ErrorCode = 0;
public int WarningCode = 0;
public Transaction TransactionInfo = null;
public PosInfo PosInformation = null;
}
and i can serialize this successfully. but when i serialize this class 2 times and save it in a XML file,multi root error appear in XML editor. i know it needs a XML element to be root to surround other tags, but i don't know how to add root element in a serialize code.
sterilizer class is below:
public class Serializer
{
public void XMLSerializer(Response response)
{
string path = "D:/Serialization.xml";
FileStream fs;
XmlSerializer xs = new XmlSerializer(typeof(Response));
if(!File.Exists(path))
{
fs = new FileStream(path, FileMode.OpenOrCreate);
}
else
{
fs = new FileStream(path, FileMode.Append);
}
StreamWriter sw = new StreamWriter(fs);
XmlTextWriter xw = new XmlTextWriter(sw);
xw.Formatting = System.Xml.Formatting.Indented;
xs.Serialize(xw, response);
xw.Flush();
fs.Close();
}
}
I would recommend improving your code to at least take care of disposable resources.
using Statement
Provides a convenient syntax that ensures the correct use of IDisposable objects.
public class Serializer
{
public void XMLSerializer(Response response)
{
string path = "D:/Serialization.xml";
var xs = new XmlSerializer(typeof(Response));
using (var fs = new FileStream(path, FileMode.OpenOrCreate))
{
using (var sw = new StreamWriter(fs))
{
using (var xw = new XmlTextWriter(sw))
{
xw.Formatting = System.Xml.Formatting.Indented;
xs.Serialize(xw, response);
xw.Flush();
}
}
fs.Close();
}
}
}
Related
The problem is simple, I want to create a method to serialize and another to open it by passing any object structure. I have the following which is what I believed should work but, guess what, it doesn't:
List<string> list = new List<string>();
list.Add("aaa");
list.Add("bbb");
FileSystem.SerializeToFile(list, "");
List<string> anotherList = FileSystem.OpenSerialized(typeof(List<string>), "");
public class FileSystem
{
public static void SerializeToFile(object toSerialize, string fileName)
{
XmlSerializer writer = new XmlSerializer(typeof(object));
StreamWriter file = new StreamWriter(fileName);
writer.Serialize(file, toSerialize);
file.Close();
}
public static object OpenSerialized(Type type, string fileName)
{
XmlSerializer serializer = new XmlSerializer(typeof(object));
StreamReader reader = new StreamReader(fileName);
object something = serializer.Deserialize(reader);
return something;
}
}
The serializer’s constructor requires a reference to the type of object it should work, slightly modified your code to fit to requirement.
public class FileSystem
{
public static void SerializeToFile<T>(T toSerialize, string fileName)
{
XmlSerializer writer = new XmlSerializer(typeof(T));
StreamWriter file = new StreamWriter(fileName);
writer.Serialize(file, toSerialize);
file.Close();
}
public static T OpenSerialized<T>(string fileName)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
StreamReader reader = new StreamReader(fileName);
object something = serializer.Deserialize(reader);
return (T)something;
}
}
and now we can use this as
List<string> list = new List<string>();
list.Add("aaa");
list.Add("bbb");
FileSystem.SerializeToFile(list, #"d:\test.txt");
List<string> anotherList = FileSystem.OpenSerialized<List<string>>(#"d:\test.txt");
Can I use an XmlWriter to write to both a file and a string?
When writing to a file I do this:
using (var xw = XmlWriter.Create("myFile.xml"))
{
//Build the xml
}
And when writing to a string I do this:
using (var sw = new StringWriter())
{
using (var xw = XmlWriter.Create(sw))
{
// Build the xml
}
return sw.ToString();
}
But can I write to both a file and a string with the same XmlWriter instance?
You could create a method like this:
private static void WriteXML(TextWriter writer)
{
using (var xw = XmlWriter.Create(writer))
{
// Build the xml
}
}
And then call it like:
using (StreamWriter sw = new StreamWriter(...))
WriteXML(sw);
to write a file or
string xml = String.Empty;
using (StringWriter sw = new StringWriter())
{
WriteXML(sw);
xml = sw.ToString();
}
To create the string.
You could even create helper methods:
private static void WriteXMLFile(string fileName)
{
using (StreamWriter sw = new StreamWriter(...))
WriteXML(sw);
}
private static string GetXML()
{
using (StringWriter sw = new StringWriter())
{
WriteXML(sw);
return sw.ToString();
}
}
Create a composite XmlWriter which wraps many XmlWriter instances.
public class CompositeXmlWriter : XmlWriter
{
private readonly IEnumerable<XmlWriter> writers;
public CompositeXmlWriter(IEnumerable<XmlWriter> writers)
{
this.writers = writers;
}
public override void WriteStartDocument()
{
foreach (var writer in writers)
{
writer.WriteStartDocument();
}
}
public override void WriteEndDocument()
{
foreach (var writer in writers)
{
writer.WriteEndDocument();
}
}
...Implement all other methods
}
Create your CompositeXmlWriter with other XmlWriters.
using (var xw = new CompositeXmlWriter(new[] { XmlWriter.Create("myFile.xml"), XmlWriter.Create(new StringWriter())})
{
//Build the xml
}
Now whatever written in xw will be written in all the XmlWriters.
I'm trying to save lists of object to a xml file. But when I'm save once it delete the before saving. I mean if I save on xml file 1 list of "Radar" and than save on the save xml file list of "Observer" it saves only the last list I save. There is any way to save them both ?
My code to save :
XmlSerializer serializer = new XmlSerializer(typeof(List<Observer>));
using (TextWriter writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListObserver.xml"))
{
serializer.Serialize(writer, list);
}
Hope you understand. Thanks in advice.
Edit :
I creat new object that contain the lists as a properties. And now All the list in one xml file.
The object :
[Serializable()]
public class SaveObject
{
public List<Radar> listRadars = new List<Radar>();
public List<Ikun> listIkuns = new List<Ikun>();
public List<Observer> listObservers = new List<Observer>();
public XmlSerializer ser;
public SaveObject(List<Observer> listObservers, List<Ikun> listIkuns,List<Radar> listRadars)
{
this.listIkuns = listIkuns;
this.listRadars = listRadars;
this.listObservers = listObservers;
}
public SaveObject()
{
ser = new XmlSerializer(this.GetType());
}
}
The serialize function :
public void Serialize(SaveObject SO)
{
if (IfPathToSave) // Select save - not auto !
{
XmlSerializer serializer = new XmlSerializer(typeof(SaveObject));
using (TextWriter writer = new StreamWriter(FilePath))
{
serializer.Serialize(writer, SO);
}
}
else // auto save !
{
XmlSerializer serializer = new XmlSerializer(typeof(SaveObject));
using (TextWriter writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\AutoSave.xml"))
{
serializer.Serialize(writer, SO);
}
}
}
Hope it will help any one sometime. Enjoy. :)
If you have 2 lists and doing it this way (wrong)
var serializer = new XmlSerializer(typeof(List<Observer>));
using (var writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListObserver.xml"))
serializer.Serialize(writer, listA);
using (var writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListObserver.xml"))
serializer.Serialize(writer, listB);
then listB will overwrite ListObserver.xml content.
You can try this
var serializer = new XmlSerializer(typeof(List<List<Observer>>));
using (var writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListObserver.xml"))
serializer.Serialize(writer, new List<List<Observer>>(new[] {listA, listB}));
If it doesn't works (for whatever reasons), then simply create serialization object
public class SerializationObject
{
public List<Observer> ListA {get; set;}
public List<Observer> ListB {get; set;}
}
and use it
var serializer = new XmlSerializer(typeof(SerializationObject));
using (var writer = new StreamWriter(#"C:\Users\user\Desktop\MapSample\bin\Debug\ListObserver.xml"))
serializer.Serialize(writer, new SerializationObject() { ListA = listA, ListB = listB });
i have question!!
=============normal===========
class trx()
{
string trx_name;
string type_id;
}
var 0 = new trx(){trx_name="1",trx_name="2"}
---Entity change to xml
[XmlSerializer serializer = new XmlSerializer(typeof(trx));
[serializer.Serialize(File.OpenWrite(#".\MyXml.xml"), o);]
----XML result------
<trx>
<trx_name>1</trx_name>
<type_id>2</type_id>
</trx>
=============================
Q: but i need trx XML
<trx>
<trx_name>a</trx_name>
<trx_name>b</trx_name>
<trx_name>c</trx_name>
<trx_name>d</trx_name>
</trx>
how to solve the question???
Thanks in advance for your help
Something like this.
public class trx
{
public string trx_name { get; set; }
}
public class CustomSerializer
{
private static void Write(string filename)
{
List<trx> trxs = new List<trx>();
trxs.Add(new trx {trx_name = "Name1"});
trxs.Add(new trx {trx_name = "Name2"});
XmlSerializer x = new XmlSerializer(typeof (List<trx>));
TextWriter writer = new StreamWriter(filename);
x.Serialize(writer, trxs);
}
private static List<trx> Read(string filename)
{
var x = new XmlSerializer(typeof (List<trx>));
TextReader reader = new StreamReader(filename);
return (List<trx>) x.Deserialize(reader);
}
}
}
I'm using a BinaryFormatter, I serialize a treeview .
Now I want to do the same thing for an ImageList
I used this code to serialize :
public static void SerializeImageList(ImageList imglist)
{
FileStream fs = new FileStream("imagelist.iml", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, imglist.ImageStream);
fs.Close();
}
and this one to deserialize :
public static void DeSerializeImageList(ref ImageList imgList)
{
FileStream fs = new FileStream("imagelist.iml", FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
imgList.ImageStream = (ImageListStreamer)bf.Deserialize(fs);
fs.Close();
}
but I get an empty string in all keys !!
ImgList.Images.Keys
why ?
Most humans do not use their full resources to cross reference what they already know. ImageList is not serializable in its current form, but there are only two things you really want to save in it and that is the Key and the Image. So you build an intermediate class to hold them, that is serializable, as in the following example:
[Serializable()]
public class FlatImage
{
public Image _image { get; set; }
public string _key { get; set; }
}
void Serialize()
{
string path = Options.GetLocalPath("ImageList.bin");
BinaryFormatter formatter = new BinaryFormatter();
List<FlatImage> fis = new List<FlatImage>();
for (int index = 0; index < _smallImageList.Images.Count; index++)
{
FlatImage fi = new FlatImage();
fi._key = _smallImageList.Images.Keys[index];
fi._image = _smallImageList.Images[index];
fis.Add(fi);
}
using (FileStream stream = File.OpenWrite(path))
{
formatter.Serialize(stream, fis);
}
}
void Deserialize()
{
string path = Options.GetLocalPath("ImageList.bin");
BinaryFormatter formatter = new BinaryFormatter();
try
{
using (FileStream stream = File.OpenRead(path))
{
List<FlatImage> ilc = formatter.Deserialize(stream) as List<FlatImage>;
for( int index = 0; index < ilc.Count; index++ )
{
Image i = ilc[index]._image;
string key = ilc[index]._key;
_smallImageList.Images.Add(key as string, i);
}
}
}
catch { }
}