XML File Serialization Issue - c#

I am trying to serializing a XML file using the following code,
using System;
using System.Xml;
using System.Xml.Serialization;
namespace TestXML
{
[Serializable]
[XmlRootAttribute("Test")]
public class Test100
{
[XmlElementAttribute("StartDate")]
public DateTime StartDate { get; set; }
[XmlElementAttribute("EndDate")]
public DateTime EndDate { get; set; }
}
class Program
{
static void Main(string[] args)
{
Test100 obj = new Test100();
try
{
XmlSerializer serializer = new XmlSerializer(typeof(Test100));
XmlReader reader = XmlReader.Create(#"C:\MyProjects\TestXML\TestXML\Test.xml");
obj = (Test100)serializer.Deserialize(reader);
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
The XML file:
<?xml version="1.0"?>
<Test>
<StartDate>2020-01-19T00:00:00Z</StartDate>
<EndDate></EndDate>
</Test>
Exception : The string '' is not a valid AllXsd value.
Thanks in advance for your help.

I updated the code as below
public string EndDate { get; set; }
[XmlIgnore]
public bool? _EndDate
{
get
{
if (!string.IsNullOrWhiteSpace(EndDate))
{
return bool.Parse(EndDate);
}
return null;
}
}
The above code is handling the null issue.

Related

Read xml attribute as object

I have the following simple XML file and I am tying to read the attribute code, using a C# .NET Core Console. I really appetite for any help.
<course type="IT" date="19.09.2019">
<line code="IT001"/>
</course>
UPDATE
I need the result as an object.
Use xml serialization to get a class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Globalization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Course));
Course course = (Course)serializer.Deserialize(reader);
}
}
[XmlRoot("course")]
public class Course
{
[XmlAttribute("type")]
public string _type { get; set; }
public DateTime _date { get; set; }
[XmlAttribute("date")]
public string date {
get { return _date.ToString("dd.MM.yyyy"); }
set { _date = DateTime.ParseExact(value, "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture); }
}
private string _code { get; set; }
[XmlElement("line")]
public Line line
{
get { return new Line() { code = _code }; }
set { _code = value.code; }
}
}
[XmlRoot("line")]
public class Line
{
[XmlAttribute("code")]
public string code { get; set; }
}
}
Many ways to skin this cat. Here is a solution by making use of XPath
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml("<course type=\"IT\" date=\"19.09.2019\"> <line code=\"IT001\"/></course>");
var attrVal = xmlDoc.SelectSingleNode("/course/line/#code").Value;
Console.WriteLine("Attribute 'code' value is " + attrVal);

C# Parse XML to Object and store into Database

I'm currently working on an ASP.NET MVC 4.6 application using SQL Server 2014 as a data storage.
I need to parse a XML document from an URL, transform the XML into an object and store it into the database using Entity Framework 6.
I need to parse the XML from an URL like this:
http: //api.myserver.com/notes.xml
My XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<notes>
<note>
<to>Tove</to>
<from>Jane</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note>
<to>Doe</to>
<from>John</from>
<heading>Meeting</heading>
<body>Hello Monday!</body>
</note>
<notes>
My model class note looks like this:
public class Note
{
public string To { get; set; }
public string From { get; set; }
public string Heading { get; set; }
public string Body { get; set; }
}
My current test implementation looks like this, BUT I'm not so happy about the parsing of the XML:
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
String url = "https://www.w3schools.com/xml/note.xml";
XmlDocument doc = new XmlDocument();
doc.Load(url);
XmlElement root = doc.DocumentElement;
StringBuilder sb = new StringBuilder();
sb.Append("<note>");
foreach (XmlNode item in root)
{
sb.Append(item.OuterXml);
}
sb.Append("</note>");
var result = Deserialize<Note>(sb.ToString());
// further processing of result using EF 6
Console.ReadKey();
}
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch (Exception ex)
{
throw;
}
}
}
[XmlRoot(ElementName = "note", Namespace = "")]
public class Note
{
[XmlElement("to")]
public string To { get; set; }
[XmlElement("from")]
public string From { get; set; }
[XmlElement("heading")]
public string Heading { get; set; }
[XmlElement("body")]
public string Body { get; set; }
}
}
As far as I noticed, .NET provides several approaches on how to parse XML:
XmlReader Class
XPath
XDocument
DataSet
LINQ
I was wondering, what would you use and how would u solve the parsing of the XML document from an URL using .NET and converting into an object to store it in a SQL Server DB?
Thanks for your help and consideration!!
This might help you, a serialize method and a Deserialize method.
public static string Serialize<T>(T dataToSerialize)
{
try
{
var stringwriter = new ISOEncodingStringWriter();
var serializer = new XmlSerializer(typeof(T));
var xns = new XmlSerializerNamespaces();
xns.Add(string.Empty, string.Empty);
serializer.Serialize(stringwriter, dataToSerialize, xns);
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;
}
}
You use the method like this:
Note result = Deserialize<Note>(xmlstring);
Note note = new Note(){...};
string convertedToXML = Serialize<Note>(note);
Just remember that you need to add some data to your note class so it can actually serialize the data:
[XmlRoot(ElementName = "root", Namespace = "")]
public class Note
{
[XmlElementAttribute("To")]
public string To { get; set; }
[XmlElementAttribute("From")]
public string From { get; set; }
[XmlElementAttribute("Heading")]
public string Heading { get; set; }
[XmlElementAttribute("Body")]
public string Body { get; set; }
}
I hope it helps :)
You can use LINQ to XML to traverse the nodes of your documents and either EF or ADO.NET to store them in the DB.
You can start with this helpful tutorial: http://www.c-sharpcorner.com/UploadFile/de41d6/learning-linq-made-easy-tutorial-1/

RoundtripKind mode xml serialize

I am using the code below in order to serialize Topology class to xml:
public static bool WriteTopologyFile(string path)
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(Topology));
using (StreamWriter reader = new StreamWriter(path))
{
serializer.Serialize(reader, Runtime.Topology);
}
return true;
}
catch (Exception ex)
{
Log.WriteEventLog(ex, EventLogEntryType.Error);
}
return false;
}
In Topology class, there are some DateTime fields and i want to serialize these DateTime fields in
System.Xml.XmlDateTimeSerializationMode.RoundtripKind
mode. How can i do that?
[XmlIgnore]
public DateTime Time { get; set; }
[XmlElement("Time")]
public string strTime
{
get { return Time.ToString("o"); }
set { Time = DateTime.Parse(value); }
}

<string xmlns=''> was not expected in c#

Hi all I am trying to serialize value in xml. Every time I am getting <string xmlns=''> was not expected in c# Not able to find root cause plz help me out here.
namespace CustomDataType.usercontrols
{
public partial class CustomDataTypes : System.Web.UI.UserControl, umbraco.editorControls.userControlGrapper.IUsercontrolDataEditor
{
private Status _umbval;
public object value
{
get
{
var status = GetStatus();
return SerializationHelper.ValueToXmlString(status);
}
set
{
//if (value == null || string.IsNullOrEmpty(value.ToString()))
//{
// _umbval = Status.Empty;
//}
//else
//{
_umbval =(Status)SerializationHelper.ValueFromXmlString(value,typeof(Status));
//}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml.Serialization;
namespace CustomDataType
{
[Serializable]
[XmlRoot("StatuMain")]
public class Status
{
[XmlElement("statusvalue")]
public string StatusValue { get; set; }
[XmlElement("statusvalue1")]
public string StatusValue1 { get; set; }
[XmlElement("statusvalue2")]
public string StatusValue2 { get; set; }
[XmlElement("statusvalue3")]
public string StatusValue3 { get; set; }
//[XmlElement("isEmailChecked")]
//public bool HasEmailChecked { get; set; }
//[XmlElement("datetime")]
//public DateTime Date { get; set; }
public static Status Empty
{
get
{
var schedule = new Status();
schedule = null;
return schedule;
}
}
}
}
I think you should be using XmlNamespaceManager to set an empty namespace, instead of xmlns..
http://msdn.microsoft.com/en-us/library/d6730bwt(v=vs.80).aspx
XmlNamespaceManager nsmanager = new XmlNamespaceManager(reader.NameTable);
nsmanager.AddNamespace("", "");
YourSeraializationMethod(reader);

Store custom application settings in XML

please help. I have this code, it's my class to serialize\deserialize application settings.
[XmlRoot("EvaStartupData")]
[Serializable]
public class MyConfigClass
{
public string ServerName { get; set; }
public string Database { get; set; }
public string UserName { get; set; }
public string UserLogin { get; set; }
public static void MyConfigLoad()
{
FileInfo fi = new FileInfo(myConfigFileName);
if (fi.Exists)
{
XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
StreamReader myXmlReader = new StreamReader(myConfigFileName);
try
{
myConfigClass = (MyConfigClass)mySerializer.Deserialize(myXmlReader);
myXmlReader.Close();
}
catch (Exception e)
{
MessageBox.Show("Ошибка сериализации MyConfigLoad\n" + e.Message);
}
finally
{
myXmlReader.Dispose();
}
}
}
public static void MyConfigSave()
{
XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
StreamWriter myXmlWriter = new StreamWriter(myConfigFileName);
try
{
mySerializer.Serialize(myXmlWriter, myConfigClass);
}
catch (Exception e)
{
MessageBox.Show("Ошибка сериализации MyConfigSave\n" + e.Message);
}
finally
{
myXmlWriter.Dispose();
}
}
}
Serialization give's me simple xml-structure:
<ServerName>navuhodonoser</ServerName>
<Database>matrix</Database>
<UserName>Mr.Smith</UserName>
<UserLogin>neo</UserLogin>
How must i modify my class to get this xml structure ?:
<Connection ServerName="navuhodonoser" Database="matrix" ....>
By default the XmlSerializer will serialize all public properties as elements; to override that you'll need to tag each property with [XmlAttribute] (from System.Xml.Serialization namespace) which will give you your desired output.
For example:
[XmlAttribute]
public string ServerName { get; set; }
[XmlAttribute]
public string Database { get; set; }
[XmlElement]
public string UserName { get; set; }
// Note: no attribute
public string UserLogin { get; set; }
will produce something like:
<xml ServerName="Value" Database="Value">
<UserName>Value</UserName> <!-- Note that UserName was tagged with XmlElement, which matches the default behavior -->
<UserLogin>Value</UserLogin>
</xml>
I have a couple of suggestions. Try code more like this:
public static void MyConfigLoad()
{
if (!File.Exists(myConfigFileName))
{
return;
}
XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
using (StreamReader myXmlReader = new StreamReader(myConfigFileName))
{
try
{
myConfigClass = (MyConfigClass)mySerializer.Deserialize(myXmlReader);
}
catch (Exception e)
{
MessageBox.Show("Ошибка сериализации MyConfigLoad\n" + e.ToString());
}
}
}
public static void MyConfigSave()
{
XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
using (StreamWriter myXmlWriter = new StreamWriter(myConfigFileName))
{
try
{
mySerializer.Serialize(myXmlWriter, myConfigClass);
}
catch (Exception e)
{
MessageBox.Show("Ошибка сериализации MyConfigSave\n" + e.ToString());
}
}
}
You should put the StreamReader and StreamWriter in using blocks so that they will be disposed even if an exception occurs. Also, I suggest you always display e.ToString() instead of just e.Message, as it will display the entire exception, including any inner exceptions.
Also, File.Exists works just like FileInfo.Exists, but doesn't require you to create an instance before using it.
One final note is that you should look into using the Settings feature instead of creating your own configuration classes. That allows you to easily create type-safe settings that can be used throughout your application, and which can be per-user or per-application.

Categories

Resources