I have tried this code but I'm not getting it. Please explain this code:
public static XmlDocument ConvertToXml(object list)
{
XmlDocument xmldoc = new XmlDocument();
XmlSerializer _XmlSerializer = new XmlSerializer(list.GetType());
using (MemoryStream xmlStream = new MemoryStream())
{
_XmlSerializer.Serialize(xmlStream, list);
xmlStream.Position = 0;
xmldoc.Load(xmlStream);
return xmldoc;
}
}
Your code should work.
You can use Generic function like this.
public static XmlDocument ObjectToXmlDocument<T>(T obj)
{
XmlDocument xmldoc = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, obj);
stream.Position = 0;
xmldoc.Load(stream);
}
return xmldoc;
}
Related
I already searched a lot and unable to find a solution and unable to determine the correct approach
I am serializing an object to xml string and deserializing it back to an object using c#. XML string after serialization adds a leading ?. When I dezerialize it back to the object I am getting an error There is an error in XML document (1, 1)
?<?xml version="1.0" encoding="utf-16"?>
Serialization code:
string xmlString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("abc", "http://example.com/abc/");
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream,Encoding.Unicode);
xs.Serialize(xmlTextWriter, obj, ns);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
xmlString = ConvertByteArrayToString(memoryStream.ToArray());
ConvertByteArrayToString:
UnicodeEncoding encoding = new UnicodeEncoding();
string constructedString = encoding.GetString(characters);
Deserialization Code:
XmlSerializer ser = new XmlSerializer(typeof(T));
StringReader stringReader = new StringReader(xml);
XmlTextReader xmlReader = new XmlTextReader(stringReader);
object obj = ser.Deserialize(xmlReader);
xmlReader.Close();
stringReader.Close();
return (T)obj;
I would like to know what I am doing wrong with encoding and I need a solution that works for most cases. Thanks
Use following function for serialization and Deserialization
public static string Serialize<T>(T dataToSerialize)
{
try
{
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stringwriter, dataToSerialize);
return stringwriter.ToString();
}
catch
{
throw;
}
}
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new System.IO.StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch
{
throw;
}
}
Your serialized XML contains a Unicode byte-order mark in the beginning, and this is where the deserializer fails.
To remove the BOM you need to create a different version of encoding suppressing BOM instead of using default Encoding.Unicode:
new XmlTextWriter(memoryStream, new UnicodeEncoding(false, false))
Here the second false prevents BOM being prepended to the string.
I have an object in c# that needs to be saved as file and reused.
So basically what I am doing now is I am serializing a class to xml and I am saving it as a file. The file is aproximatelly 100MB.
Now the problem I am experiencing is when I want to deserialize file to class, I and up with OutOfMemoryException.
I am using the following code:
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(file);
Deserialize<T>(xmlDocument.InnerXml);
public static T Deserialize<T>(string xmlContent)
{
var inStream = new StringReader(xmlContent);
var ser = new XmlSerializer(typeof(T));
return (T)ser.Deserialize(inStream);
}
Here's what my comment would look like in code:
public static T Deserialize<T>(string Filepath)
{
using (FileStream FStream = new FileStream(Filepath, FileMode.Open))
{
var Deserializer = new XmlSerializer(typeof(T));
return (T)Deserializer.Deserialize(FStream);
}
}
My method returns Dictionary<TZerokey, Dictionary<TFirstKey, Dictionary<TSecondKey,Dictionary<TThirdKey,TValue>>>> and i would to serialise/deserialise this object as XML using DataContractSerialiser.
Below are my methods:
public static void SerializeDictionaryToXml<T>(this T obj, string fileName)
{
DataContractSerializer ser = new DataContractSerializer(typeof(T));
// System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));
FileStream fileStream = new FileStream(fileName, FileMode.Create);
ser.WriteObject(fileStream, obj);
fileStream.Close();
}
public static T DeserializeDictionaryFromXml<T>(string xml)
{
FileStream fs = new FileStream(xml,
FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
DataContractSerializer ser = new DataContractSerializer(typeof(T));
// Deserialize the data and read it from the instance.
T deserializedObject = (T)ser.ReadObject(reader, true);
reader.Close();
fs.Close();
return deserializedObject;
}
The code runs fine except that I do not get the expected output. Can someone see what I'm doing wrong?
I am using this method to transform an object to XML:
protected XmlDocument SerializeAnObject(object obj)
{
XmlDocument doc = new XmlDocument();
DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
MemoryStream stream = new MemoryStream();
try
{
serializer.WriteObject(stream, obj);
stream.Position = 0;
doc.Load(stream);
return doc;
}
finally
{
stream.Close();
stream.Dispose();
}
}
Eventually I get something like:
<CaCT>
<CTC i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/a.b.BusinessEntities.InnerEntities" />
<CTDescr xmlns="http://schemas.datacontract.org/2004/07/a.b.BusinessEntities.InnerEntities">blabla</CTDescr>
<CaId>464</CaId>
</CaCT>
How can I get rid of the i:nil="true" and the xmlns="http://schemas.datacontract.org/2004/07/a.b.BusinessEntities.InnerEntities"?
Personally I've always found that hand-written XML serialization with LINQ to XML works well. It's as flexible as you want, you can make it backward and forward compatible in whatever way you want, and obviously you don't end up with any extra namespaces or attributes that you don't want.
Obviously it becomes more complicated the more complicated your classes are, but I've found it works very well for simple classes. It's at least an alternative to consider.
protected string SerializeAnObject(object obj)
{
XmlSerializerNamespaces xmlNamespaces = new XmlSerializerNamespaces();
xmlNamespaces.Add("", "");
XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.OmitXmlDeclaration = true;
XmlSerializer serializer = new XmlSerializer(obj.GetType());
using (MemoryStream ms = new MemoryStream())
{
using (XmlWriter stream = XmlWriter.Create(ms, writerSettings))
{
serializer.Serialize(stream, obj, xmlNamespaces);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
I have the following variable that accepts a file name:
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
I would like to change it so that I can pass in an object. I don't want to have to serialize the object to file first.
Is this possible?
Update:
My original intentions were to take an xml document, merge some xslt (stored in a file), then output and return html... like this:
public string TransformXml(string xmlFileName, string xslFileName)
{
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
xslt.Load(xslFileName);
var stm = new MemoryStream();
xslt.Transform(xd, null, stm);
stm.Position = 1;
var sr = new StreamReader(stm);
xtr.Close();
return sr.ReadToEnd();
}
In the above code I am reading in the xml from a file. Now what I would like to do is just work with the object, before it was serialized to the file.
So let me illustrate my problem using code
public string TransformXMLFromObject(myObjType myobj , string xsltFileName)
{
// Notice the xslt stays the same.
// Its in these next few lines that I can't figure out how to load the xml document (xd) from an object, and not from a file....
var xtr = new XmlTextReader(xmlFileName) { WhitespaceHandling = WhitespaceHandling.None };
var xd = new XmlDocument();
xd.Load(xtr);
}
You want to turn an arbitrary .NET object into a serialized XML string? Nothing simpler than that!! :-)
public string SerializeToXml(object input)
{
XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
string result = string.Empty;
using(MemoryStream memStm = new MemoryStream())
{
ser.Serialize(memStm, input);
memStm.Position = 0;
result = new StreamReader(memStm).ReadToEnd();
}
return result;
}
That should to it :-) Of course you might want to make the default XML namespace configurable as a parameter, too.
Or do you want to be able to create an XmlDocument on top of an existing object?
public XmlDocument SerializeToXmlDocument(object input)
{
XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
XmlDocument xd = null;
using(MemoryStream memStm = new MemoryStream())
{
ser.Serialize(memStm, input);
memStm.Position = 0;
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = true;
using(var xtr = XmlReader.Create(memStm, settings))
{
xd = new XmlDocument();
xd.Load(xtr);
}
}
return xd;
}
You can serialize directly into the XmlDocument:
XmlDocument doc = new XmlDocument();
XPathNavigator nav = doc.CreateNavigator();
using (XmlWriter w = nav.AppendChild())
{
XmlSerializer ser = new XmlSerializer(typeof(MyType));
ser.Serialize(w, myObject);
}
Expanding on #JohnSaunders solution I wrote the following generic function:
public XmlDocument SerializeToXml<T>(T source) {
var document = new XmlDocument();
var navigator = document.CreateNavigator();
using (var writer = navigator.AppendChild()) {
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, source);
}
return document;
}