Serilializing Linq.Table to XML - c#

I have a very simple application which currently has a single Linq to Sql class based on a single table.
I need to serialize (to XML) all rows in the table using the DataContext for the Linq To Sql class.
How do I go about doing this?
This is my current code :
var db = new MyEntityDataContext();
Stream fs = new FileStream("Output.xml", FileMode.Create);
XmlWriter writer = new XmlTextWriter(fs, Encoding.Unicode);
serializer = new XmlSerializer(typeof(MyEntity));
foreach (var row in db.MyEntitys)
{
// Serialize object to XML
serializer.Serialize(writer,row);
}
writer.Close();
However it throws the following exception:
"Token StartElement in state Epilog would result in an invalid XML document."
I have also tried:
XmlSerializer serializer2 = new XmlSerializer(db.MyEntitys.GetType());
but this throws a
"To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy."
exception.

XmlSerializer may not be wonderful with associations. If you enable serialization on the data-context surface, it adds (WCF) data-contract attributes. Perhaps just use:
var data = db.MyEntitys.ToList();
var ser = new DataContractSerializer(data.GetType());
ser.WriteObject(dest, data);

Related

C# - Allow any order of elements in XSD file after generating it with XMLSchemaInference

I'm writing a code which is generating XSD file from XML data sample by using C# XMLSchemaInference class within the following code
XmlReader reader = XmlReader.Create(xml);
XmlSchemaSet schemaSet = new XmlSchemaSet();
XmlSchemaInference schema = new XmlSchemaInference();
schema.Occurrence = XmlSchemaInference.InferenceOption.Relaxed; //Setting minimum occurences to 0 (nullable elements)
schemaSet = schema.InferSchema(reader);
XmlWriter writer;
foreach (XmlSchema xmls in schemaSet.Schemas())
{
var dest = Path.ChangeExtension(Path.Combine(xsdDirectory, Path.GetFileName(xml)), "xsd");
writer = XmlWriter.Create(dest);
xmls.Write(writer);
writer.Close();
}
reader.Close();
However, the result XSD contains <<xs:sequence>> elements which wont allow XML elements to be in a different order. Is there a way of trustworthy replacing the <<xs:sequence>> for <<xs:all>> in places where it is mandatory? If there is an element which can occur more times it can be seen in that XML data sample. I'm surprised that I'm not able to find this option in the official tool XmlSchemaInference.

Serializing a generic binary search tree with a bunch of child objects, including a binary tree

I've got a very complex binary search tree. It's node data should keep an object of custom KeyValue class. As a key there should be a string, and value is another tree, which data field contains an object of custom KeyValue class, where key is a string and value is string[].
I need to serialize and deserialize it, using XML serializer.
The problem is that serialization isn't done properly. XML file does not contain Nodes as elements, only their data.
Therefore, it can't be deserialized, a new tree's root is null.
Here is how I perform serialization.
XmlSerializer XMLserializer = new XmlSerializer(typeof(RecursiveKeyValueTree<string, RecursiveKeyValueTree<string, string[]>>), extraTypes);
XmlSerializerNamespaces myNamespace = new XmlSerializerNamespaces();
myNamespace.Add("", "");
using (FileStream serializationStream = File.Create("dictionaryTreeExample.xml"))
XMLserializer.Serialize(serializationStream, dictionaryTree, myNamespace);
RecursiveKeyValueTree<string, RecursiveKeyValueTree<string, string[]>> dictionaryTreeDeserialized;
using (FileStream deserializationStream = File.OpenRead("dictionaryTreeExample.xml"))
{
dictionaryTreeDeserialized = (RecursiveKeyValueTree<string, RecursiveKeyValueTree<string, string[]>>)XMLserializer.Deserialize(deserializationStream);
}
XML file:
My Add() method in the binary tree had an unnecessary check before inserting elements, thus, it prevented elements of the outer tree from being inserted.

In .NET is there any way to convert an CSV value to XML based on predefined XML template?

I am using .NET and trying to convert an CSV data input (Example 1st row is header and following rows are the data: header1,header2,header3;row11,row12,row13;row21,row22,row23). Trying to convert this into XML format based on another XML template (there are multiple XML templates based on which the corresponding XML should be generated)
What is best practice to do this in .NET?
Sample template1:
<Claims>
<Claim>
<Header1></Header1>
<Header2></Header2>
<Header3></Header3>
</Claim>
</Claims>
Sample template2:
<Handlers>
<Handler>
<Header2></Header2>
<Header3></Header3>
<Header1></Header1>
</Handler>
</Handlers>
You should find a library that deserilizes CSV's then just serialize it into Xml using the XmSerializer.
Ie, using something like CsvHelper
var csv = new CsvReader( File.OpenText( "file.csv" ) );
var myCustomObjects = csv.GetRecords<MyCustomObject>();
Then get that resulting object and serialize into Xml:
XmlSerializer serializer = new XmlSerializer(typeof(MyCustomObject));
var subReq = new MyCustomObject();
StringWriter sww = new StringWriter();
XmlWriter writer = XmlWriter.Create(sww);
serializer.Serialize(writer, subReq);
var xml = sww.ToString(); // Your xml

Convert List<Object> to XML

I have a very simple application. MainUI has the List of CustomClass. I pass this list to WCF service. WCF Service further needs to save these objects in database.
I am using Open XML in our sql stored procedure to get better performnace. But i don't know how to convert my List of Objects to XML.
If i have a datatable, it'll be easy as datatables have methods to get the XML out of them. But how to use for List of objects.
I completly understand that if my List is coming over the WCF, it is getting serialized properly. But what should i exactly need to do.
IMO, look into Controlling XML Serialization with Attributes and the XmlSerializer class and possibly create container classes parallel to your CustomClass. While List<> can't be automatically serialized by the default XML serializer, an array can be.
Thera are two ways: use XmlSerializer or DataContractSerializer.
Code for convert list to xml : List name GridDetails
void ConvertToXml()
{
string xmlString = ConvertObjectToXMLString(GridDetails);
// Save C# class object into Xml file
XElement xElement = XElement.Parse(xmlString);
xElement.Save(#"C:\Users\user\Downloads\userDetail.xml");
}
static string ConvertObjectToXMLString(object classObject)
{
string xmlString = null;
XmlSerializer xmlSerializer = new XmlSerializer(classObject.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
xmlSerializer.Serialize(memoryStream, classObject);
memoryStream.Position = 0;
xmlString = new StreamReader(memoryStream).ReadToEnd();
}
return xmlString;
}

How to use XmlReader class?

I want to save and load my xml data using XmlReader. But I don't know how to use this class. Can you give me a sample code for start?
MSDN has a simple example to get you started here.
If you're interested in reading and writing XML documents, and not just specifically using the XmlReader class, there's a nice article covering a few of your options here.
But if you just want to get started and play around, try this:
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = true;
settings.IgnoreComments = true;
XmlReader reader = XmlReader.Create("file.xml", settings);
Personally I have switched away from XMLReader to System.XML.Linq.XDocument to manage my XML data files. This way I can easily pull data from xml into objects and manage them like any other object in my program. When I am done manipulating them I can just save the changes back out the the xml file at any time.
//Load my xml document
XDocument myData = XDocument.Load(PhysicalApplicationPath + "/Data.xml");
//Create my new object
HelpItem newitem = new HelpItem();
newitem.Answer = answer;
newitem.Question = question;
newitem.Category = category;
//Find the Parent Node and then add the new item to it.
XElement helpItems = myData.Descendants("HelpItems").First();
helpItems.Add(newitem.XmlHelpItem());
//then save it back out to the file system
myData.Save(PhysicalApplicationPath + "/Data.xml");
If I want to use this data in an easily managed data set I can bind it to a list of my objects.
List<HelpItem> helpitems = (from helpitem in myData.Descendants("HelpItem")
select new HelpItem
{
Category = helpitem.Element("Category").Value,
Question = helpitem.Element("Question").Value,
Answer = helpitem.Element("Answer").Value,
}).ToList<HelpItem>();
Now it can be passed around and manipulated with any inherent functions of my object class.
For convenience my class has a function to create itself as an xml node.
public XElement XmlHelpItem()
{
XElement helpitem = new XElement("HelpItem");
XElement category = new XElement("Category", Category);
XElement question = new XElement("Question", Question);
XElement answer = new XElement("Answer", Answer);
helpitem.Add(category);
helpitem.Add(question);
helpitem.Add(answer);
return helpitem;
}
You should use the Create method instead of using new, since XmlReader is an abstract class using the Factory pattern.
var xmlReader = XmlReader.Create("xmlfile.xml");
From the excellent C# 3.0 in a Nutshell, consider looking at the sample code from chapter 11.

Categories

Resources