Can you Serialize inside a set of Attributes by Set of Attributes? - c#

I want a serialize a set of attributes all together to an XML file in a loop that runs. This loop runs within a set of folders . According to my Current implementation It only shows the last set of Attributes.
Here is my Current code ,
Student obj = JsonConvert.DeserializeObject < StudentModel (File.ReadAllText(file));
string Name = studentModel.name;
string number = studentModel.number;
string testPath = rootDirectory;
XmlSerializer serializer = new XmlSerializer(typeof(StudentModel));
System.IO.StreamWriter writer = new System.IO.StreamWriter(testPath + "\\Test.xml");
serializer.Serialize(writer, studentModel);
writer.Close();
My Current output is
<?xml version="1.0" encoding="utf-8"?>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Max</name>
<number>1</number>
</StudentModel>
Required output is
<?xml version="1.0" encoding="utf-8"?>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Max</name>
<number>1</number>
</StudentModel>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Amy</name>
<number>2</number>
</StudentModel>
<StudentModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Jack</name>
<number>3</number>
</StudentModel>

It seems to me, that what you want to do is serialize a list (or array) of StudentModel to an xml. Currently you are only serializing one instance of StudentModel and overwrite the resulting xml each iteration of the loop, leaving you with the last item. What you can do, is to create a class with a List() of StudentModel as Property and serialize that class instance, not needing a loop anymore.
The List property in your new class would then look something like this:
[XmlArray("StudentModels"), XmlArrayItem(typeof(StudentModel), ElementName = "StudentModel")]
public List<StudentModel> StudentModelList{ get; set; }

Related

C# - How to serialize and derialize DataSet correctly?

I cannot deserialize the serialized dataset correctly if it has dates. The result is the dates are considered as a separate table instead of columns itself. It seems that it is not parsed correctly. How do I fix this?
Here are the variables under inspection after the serialization and deserialization. You can see that the deserializedDataSet.Tables has 2 counts where its original is just 1 count. I printed the table names and shows that the second table was date. Moreover, I can access the date column in the original data set but unable to access in the deserialized version.
Here is the serialized data of the dataset.
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<producttransactionsummary>
<id>74517</id>
<branchid>9999</branchid>
<date xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Year>2016</Year>
<Month>11</Month>
<Day>10</Day>
<Hour>18</Hour>
<Minute>25</Minute>
<Second>40</Second>
<Millisecond>0</Millisecond>
</date>
</producttransactionsummary>
<producttransactionsummary>
<id>74518</id>
<branchid>9999</branchid>
<date xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Year>2016</Year>
<Month>11</Month>
<Day>10</Day>
<Hour>18</Hour>
<Minute>25</Minute>
<Second>40</Second>
<Millisecond>0</Millisecond>
</NewDataSet>
Here is the deserialized dataset.
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<producttransactionsummary>
<id>74517</id>
<branchid>9999</branchid>
<date>
<Year>2016</Year>
<Month>11</Month>
<Day>10</Day>
<Hour>18</Hour>
<Minute>25</Minute>
<Second>40</Second>
<Millisecond>0</Millisecond>
</date>
</producttransactionsummary>
<producttransactionsummary>
<id>74518</id>
<branchid>9999</branchid>
<date>
<Year>2016</Year>
<Month>11</Month>
<Day>10</Day>
<Hour>18</Hour>
<Minute>25</Minute>
<Second>40</Second>
<Millisecond>0</Millisecond>
</date>
</producttransactionsummary>
</NewDataSet>
Here is my current code:
public static class Transport
{
public static MemoryStream Serialize(DataSet dataSet)
{
var memoryStream = new MemoryStream();
dataSet.WriteXml(memoryStream, XmlWriteMode.IgnoreSchema);
dataSet.WriteXml("input.xml");
memoryStream.Flush();
memoryStream.Position = 0;
return memoryStream;
}
public static DataSet Deserialize(MemoryStream stream)
{
var dataSet = new DataSet();
dataSet.ReadXml(stream);
dataSet.WriteXml("output.xml");
return dataSet;
}
}

Change order of xmlnamespace

I was working on Xml serialization. My class is
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
[XmlInclude(typeof(Url))]
public class UrlSet
{
[XmlAttribute("schemaLocation", Namespace = XmlSchema.InstanceNamespace)]
public string xsiSchemaLocation = "http://www.sitemaps.org/schemas/sitemap/0.9" +
"http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd";
}
Tried adding
XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Output its giving to me is
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
I need to have
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
I also tried adding empty namespace, But that adds prefix q to every element in xml. I also want to know if that order really matters as I am going to submit generated sitemap to google
Any solutions?

Regarding C# Xml Reading

I'm currently doing a XML file that includes the "name" of the city, the "region", "lat" latitude and "lng".
Here is my Code:
XmlDocument XmlFile = new XmlDocument();
try {
XmlFile.Load("..\\..\\liste.xml");
}
catch (Exception ex)
{
Console.WriteLine("Erreur" + ex.Message);
};
XmlNodeList MyNodeXML = XmlFile.GetElementsByTagName("city");
foreach (XmlNode unNode in MyNodeXML)
{
string nomVille = unNode.Attributes[0].Value;
string lat = unNode.Attributes[1].Value;
string lng = unNode.Attributes[2].Value;
listeCooVilles.Add(nomVille, new PointF(float.Parse(lat), float.Parse(lng)));
}
Where listeCooVilles is a Dictionnary.
Here is my XML: I did a sample for test:
<?xml version="1.0" encoding="UTF-8"?>
<cities>
<city>
<name>Abercorn</name>
<region>Montérégie</region>
<lat>45.032999</lat>
<lng>-72.663057</lng>
</city>
<cities>
I saw many post doing the same as above in StackOverflow, but I still get an IndexOutOfRange Exception on the line
string nomVille = unNode.Attributes[0].Value;
Can someone help? Thanks!
The element has no attributes - only sub-elements. Attributes are name=value pairs at the same level as the element. E.g.
<?xml version="1.0" encoding="UTF-8"?>
<cities>
<city name="Abercorn" region="Montérégie" lat="45.032999" lng="-72.663057" />
<city name="Granby" region="Montérégie" lat="45.4" lng="-72.733333" />
</cites>
Nesting elements (as you have done originally) and using attributes (as you've coded for) are both equally valid ways of structuring your XML document.
As pointed our those are elements not attributes. Your code needs to change to this:
nomVille = unNode.Item["name"].Value
region = unNode.Item["region"].Value
lat = unNode.Item["lat"].Value
lng = unNode.Item["lng"].Value
None of the nodes in your XML sample have attributes, which is why the collection has null elements in it.
Try changing it to:
<?xml version="1.0" encoding="UTF-8"?>
<cities>
<city testAttr = "hello!">
<name>Abercorn</name>
<region>Montérégie</region>
<lat>45.032999</lat>
<lng>-72.663057</lng>
</city>
<cities>
The addition of the testAttr should provide a valid collection in unNode.Attributes.
You are using attributes in city tag but I think you should be using xml elements.

Serialize XML and append new elements to XML file

I have created a XML class using XSD2Code from my XML Schema. The class having a method SaveToFile. So when I am trying to add new elements and save it to the XML file it overwrites the entire content.
Does anyone have idea how to insert elements(append to the XML) to the XML file via Serialization.
eg:
<?xml version="1.0" encoding="utf-8"?>
<root>
<element>content1</element>
</root>
If this is the XML file I need to add an element and the resulting should come as like below using Serialization.
<?xml version="1.0" encoding="utf-8"?>
<root>
<element>content1</element>
<element>content2</element>
</root>
Your request would seem to be resolvable by adding another item into your List collection.
MyTypeFromXmlSchema myType = new MyTypeFromXmlSchema();
myType.MyElementItems = new List<MyElementItem>();
myType.MyElementItems.Add { new MyElementItem { value = "value1" } };
myType.MyElementItems.Add { new MyElementItem { value = "value2" } };
Then serialize type using XmlSerializer.

Add namespaces to serialized xml

I've got a pretty nasty problem with xml serialization - I need to add some special information to the resulting xml-file:
Currently, it looks like
<?xml version="1.0" encoding="iso-8859-1"?>
<ORDER_LIST>
<ORDER version="1.0" xmlns="http://www.opentrans.org/XMLSchema/1.0">... shortened ...</ORDER>
<ORDER version="1.0" xmlns="http://www.opentrans.org/XMLSchema/1.0">... shortened ...</ORDER>
<ORDER version="1.0" xmlns="http://www.opentrans.org/XMLSchema/1.0">... shortened ...</ORDER>
</ORDER_LIST>
but it should look like
<?xml version="1.0" encoding="iso-8859-1"?>
<ORDER_LIST>
<ORDER xmlns="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" type="standard">... shortened ...</ORDER>
<ORDER xmlns="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" type="standard">... shortened ...</ORDER>
<ORDER xmlns="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" type="standard">... shortened ...</ORDER>
</ORDER_LIST>
The additional namespace (xmlns:xsi) and the xsi:schemaLocation / type attributes should be added to the result.
Actually my code is:
[XmlTypeAttribute(Namespace="http://www.opentrans.org/XMLSchema/1.0")]
public class OrderContainer
{
[XmlElementAttribute("ORDER")]
public List<ORDER> orderList;
}
---- snip ----
string xmlString;
XmlWriterSettings settings = new XmlWriterSettings()
{
Encoding = Encoding.GetEncoding("ISO-8859-1"),
Indent = true,
IndentChars = "\t",
NewLineChars = Environment.NewLine,
ConformanceLevel = ConformanceLevel.Document,
};
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
var testOrder = new ORDER();
var orderContainer = new OrderContainer();
orderContainer.orderList = new List<ORDER>();
orderContainer.orderList.Add(testOrder);
XmlSerializer serializer = new XmlSerializer(typeof(List<ORDER>), new XmlRootAttribute("ORDER_LIST"));
using (MemoryStream ms = new MemoryStream())
{
using (XmlWriter writer = XmlTextWriter.Create(ms, settings))
serializer.Serialize(writer, orderList, ns);
xmlString = Encoding.ASCII.GetString(ms.ToArray());
}
Console.WriteLine(xmlString);
It works really fine - except for the namespaces and attributes on the ORDER elements.
Background-information: The ORDER class is created from the openTrans-definition (opentrans_order_1_0_all_in_one.xsd).
It's been translated into C# classes using Xsd2Code (Xsd2Code).
Because of the automatic generation, adorning the class with attributes is not easily possible - I guess?
Thanks for any hint!
(Edited some information)
I know its a little late to reply to this question, but nonetheless I am answering in case someone in need stumbles upon this question.
I order to add namespaces you need to use this class: System.Xml.Serialization. XmlSerializerNamespaces, which I see in the problem code that it has been defined.
Following is the syntax that I have used to add namespaces while dealing with the xCBL Xml Schema:
[XmlNamespaceDeclarations]
public XmlSerializerNamespaces xmlns; //Defined as the Field of the class you want to serialize
//Defined in the Constructor
xmlns = new XmlSerializerNamespaces();
xmlns.Add("core", "rrn:org.xcbl:schemas/xcbl/v4_0/core/core.xsd");
This will add the namespace in the generated Xml like this:
xmlns:core="rrn:org.xcbl:schemas/xcbl/v4_0/core/core.xsd"
What it should look like is:
<?xml version="1.0" encoding="iso-8859-1"?>
<ORDER_LIST xmlns:trans="http://www.opentrans.org/XMLSchema/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opentrans.org/XMLSchema/1.0 http://www.opentrans.org/XMLSchema/1.0 openTRANS_ORDER_1_0_all_in_one.xsd" version="1.0" >
<trans:ORDER type="standard" >... shortened ...</ORDER>
<trans:ORDER type="standard" >... shortened ...</ORDER>
<trans:ORDER type="standard" >... shortened ...</ORDER>
</ORDER_LIST>
I'm not familar with xsd2code, but if you were hand coding, you need to put attributes.
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.opentrans.org/XMLSchema/1.0")]
[System.Xml.Serialization.XmlElementAttribute("Order")]
public class Order() {
String Type
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://www.opentrans.org/XMLSchema/1.0")]
[System.Xml.Serialization.XmlRootAttribute("OrderList", Namespace="http://www.opentrans.org/XMLSchema/1.0", IsNullable=false)]
public class OrderList() {
List<Orders>
}
try this. it's a libary to create or read opentrans documents!
http://opentrans.wordpress.com/

Categories

Resources