I have the following XML which I need to deserialize:
<?xml version="1.0" encoding="UTF-8" ?>
<event code="2wuj0ticofhzt" self="/events/2wuj0ticofhzt" revision="1260234836">
<name>Test Event 2013</name>
<partner-settings>
<partner-setting>
<registration-type code="1yfopbwhk" link="/registration-types/1yfopbwhk" />
<personnel code="3eclag1dsrjfi">
<free-badges>unlimited</free-badges>
</personnel>
<personnel code="0nxgc6mfec8yh">
<free-badges>3</free-badges>
</personnel>
</partner-setting>
<partner-setting>
<registration-type code="1ygg67prw" link="/registration-types/1ygg67prw" />
</partner-setting>
</partner-settings>
</event>
Here are my classes that I have created. (I only need to deserialize the fields I have in my classes.):
[XmlRoot("event")]
public class Event
{
[XmlAttribute("code")]
public string Code { get; set; }
[XmlAttribute("name")]
public string EventName { get; set; }
[XmlArray("partner-settings")]
public List<PartnerSetting> PartnerSettings { get; set; }
}
[XmlType("partner-setting")]
public class PartnerSetting
{
[XmlElement("registration-type")]
public RegistrationType RegistrationType { get; set; }
[XmlArray("personnel")]
public List<Personnel> Personnel { get; set; }
}
[XmlRoot("registration-type")]
public class RegistrationType
{
[XmlAttribute("code")]
public string Code { get; set; }
[XmlAttribute("name")]
public string RegistrationTypeName { get; set; }
[XmlElement("type")]
public string Type { get; set; }
}
[XmlType("personnel")]
public class Personnel
{
[XmlAttribute("code")]
public string Code { get; set; }
[XmlElement("free-badges")]
public int FreeBadges { get; set; }
}
When I currently deserialize the above XML it all works except from the Personnel object where I get 0 returned when I'm expecting to see 2.
I'm not doing anything differently when I'm trying to return a personnel list (i.e. XMLArray attribute, return a List) to a partner setting list but for some reason it won't deserialize.
You need to change the attribute into XmlElement to force each element in the list to be rendered as a single XML element:
[XmlElement("personnel")]
public List<Personnel> Personnel { get; set; }
Related
I have following two files and Because both files having the same structure, I would like to keep one class and refer it multiple times.
XML File1:
<?xml version="1.0" encoding="utf-16"?>
<TRANSFERS>
<TR_DOCTOR_MR>
<REFDOC_CODE>MR Code</REFDOC_CODE>
<REFDOC_HOSPITALKEY>Hospital 1</REFDOC_HOSPITALKEY>
<REFDOC_RIZIV>Riziv 1</REFDOC_RIZIV>
<REFDOC_NAME>Name 1</REFDOC_NAME>
<REFDOC_FNAME>FName 1</REFDOC_FNAME>
<REFDOC_TITLE>Mr.</REFDOC_TITLE>
<REFDOC_INITIALS>RI11</REFDOC_INITIALS>
<REFDOC_FREEFIELD1>FF1</REFDOC_FREEFIELD1>
<REFDOC_FREEFIELD2>FF2</REFDOC_FREEFIELD2>
<REFDOC_FREEFIELD3>FF3</REFDOC_FREEFIELD3>
</TR_DOCTOR_MR>
</TRANSFERS>
XML File2:
<?xml version="1.0" encoding="utf-16"?>
<TRANSFERS>
<TR_DOCTOR_RESP>
<ATDOC_CODE>Ref Doctor</ATDOC_CODE>
<ATDOC_HOSPITALKEY>Hosp 2</ATDOC_HOSPITALKEY>
<ATDOC_RIZIV>Riziv 2</ATDOC_RIZIV>
<ATDOC_NAME>Name 2</ATDOC_NAME>
<ATDOC_FNAME>FName 2</ATDOC_FNAME>
<ATDOC_TITLE>Mr.</ATDOC_TITLE>
<ATDOC_INITIALS>AI22</ATDOC_INITIALS>
<ATDOC_FREEFIELD1>FF1</ATDOC_FREEFIELD1>
<ATDOC_FREEFIELD2>FF2</ATDOC_FREEFIELD2>
<ATDOC_FREEFIELD3>FF3</ATDOC_FREEFIELD3>
</TR_DOCTOR_RESP>
</TRANSFERS>
Here is the C# code:
[XmlRoot("TRANSFERS")]
public class TransferXml
{
[XmlElement("TR_DOCTOR_MR")]
public TransferDoctorXml TR_DOCTOR_MR { get; set; }
[XmlElement("TR_DOCTOR_RESP")]
public TransferDoctorXml TR_DOCTOR_RESP { get; set; }
}
public class TransferDoctorXml
{
[XmlElement("ATDOC_CODE")]
[XmlElement("REFDOC_CODE")]
public string Code { get; set; }
[XmlElement("ATDOC_HOSPITALKEY")]
[XmlElement("REFDOC_HOSPITALKEY")]
public string HospitalKey { get; set; }
[XmlElement("ATDOC_RIZIV")]
[XmlElement("REFDOC_RIZIV")]
public string Riziv { get; set; }
[XmlElement("ATDOC_NAME")]
[XmlElement("REFDOC_NAME")]
public string LastName { get; set; }
[XmlElement("ATDOC_FNAME")]
[XmlElement("REFDOC_FNAME")]
public string FirstName { get; set; }
[XmlElement("ATDOC_TITLE")]
[XmlElement("REFDOC_TITLE")]
public string Title { get; set; }
[XmlElement("ATDOC_INITIALS")]
[XmlElement("REFDOC_INITIALS")]
public string Initials { get; set; }
[XmlElement("ATDOC_FREEFIELD1")]
[XmlElement("REFDOC_FREEFIELD1")]
public string FreeField1 { get; set; }
[XmlElement("ATDOC_FREEFIELD2")]
[XmlElement("REFDOC_FREEFIELD2")]
public string FreeField2 { get; set; }
[XmlElement("ATDOC_FREEFIELD3")]
[XmlElement("REFDOC_FREEFIELD3")]
public string FreeField3 { get; set; }
}
I want both files refer to the same C# class for deserialization to avoid duplicates and have code clean and maintainable. However, it doesn't work like this. I have googled a lot to find out if this is possible. But couldn't find it. Can anyone please help me?
string DoctorMr = File.ReadAllText("C:\\TEMP\\TransferDoctorMr.xml");
TransferXml drXml = XmlHelper<TransferXml>.DeserializeObject(DoctorMr);
Thank you.
I have some data in an XML file. I am trying to deserialize the XML to some classes I have created.
I have been able to deserialize all the attributes of the PointCode and CodeAttributes elements. However, I can't seem to get the TextListValue attribute of the textList element.
The textList element returns a null value.
I am using c# and using System.Xml.Serialization
[XmlRoot("PointCode")]
public class PointCode
{
[XmlAttribute("codeLinework")]
public string codeLinework { get; set; }
[XmlElement("CodeAttributes")]
public List<CodeAttributes> codeAttributes { get; set; }
}
[XmlRoot("CodeAttributes")]
public class CodeAttributes
{
[XmlAttribute("attributeName")]
public string attributeName { get; set; }
[XmlAttribute("attributeType")]
public string attributeType { get; set; }
[XmlAttribute("valueType")]
public string valueType { get; set; }
[XmlAttribute("valueRegion")]
public string valueRegion { get; set; }
[XmlElement("text")]
public Text text { get; set; }
}
[XmlRoot("text")]
public class Text
{
[XmlElement("textChoiceList")]
public TextChoiceList textChoiceList { get; }
}
[XmlRoot("textChoiceList")]
public class TextChoiceList
{
[XmlElement("textList")]
public List<TextList> textList { get; set; }
}
[XmlRoot("textList")]
public class TextList
{
[XmlAttribute("textListValue")]
public string textListValue { get; set; }
}
Extract of the XML file I am deserializing.
<Code codeName="KERB" codeDesc="Kerbs" codeType="Point">
<PointCode codeLinework="open line">
<CodeAttributes attributeName="String" attributeType="Normal" valueType="Integer" valueRegion="None">
<integer />
</CodeAttributes>
<CodeAttributes attributeName="Type" attributeType="Normal" valueType="Text" valueRegion="ChoiceList">
<text>
<textChoiceList>
<textList textListValue="Square Kerb" />
<textList textListValue="Roll Kerb" />
</textChoiceList>
</text>
</CodeAttributes>
The missing setter for textChoiceList property in the Text class that leads to the text was null as the only property in the class is unable to set value.
So adding the missing setter to the property will solve the issue.
[XmlRoot("text")]
public class Text
{
[XmlElement("textChoiceList")]
public TextChoiceList textChoiceList { get; set; }
}
Sample .NET Fiddle
I have an XML file that looks something similar to this:
<root>
<data label="product data" min="0" max="10">
<option>
<id>1</id>
<name>Name1</name>
</option>
<option>
<id>2</id>
<name>Name2</name>
</option>
<option>
<id>3</id>
<name>Name3</name>
</option>
</data>
</root>
I need to retreive both data attributes and the option list.
I tried this:
[XmlRoot(ElementName = "root")]
public class Data
{
// Retreive data attributes
[XmlElement(ElementName = "data")]
public Options Attributes { get; set; }
// Retrieve option list
[XmlArray("data")]
[XmlArrayItem("option", Type = typeof(GeneralOptions))]
public GeneralOptions[] Options { get; set; }
}
Optional classes:
Options
public class Options
{
[XmlAttribute("label")]
public string Label{ get; set; }
[XmlAttribute("min")]
public string Min{ get; set; }
[XmlAttribute("max")]
public string Max{ get; set; }
}
GeneralOptions
public class GeneralOptions
{
[XmlElement(ElementName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "name")]
public string Name{ get; set; }
}
But when I try to deserialize the object, it launches the following exception:
The XML element 'data' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.
I imagine the problem is that I'm trying to retreive the same element "twice". But I need to retreive both things. I cannot use the [Attribute] thing because there are several Attributes to retreive, and I need to do this with several XML Elements with the same format and I want to reuse it.
So, how can I retreive both of them?
You'll need to restructure it slightly:
[XmlRoot("root")]
public class Data
{
[XmlElement("data")]
public OptionsData Options { get; set; }
}
public class OptionsData
{
[XmlAttribute("label")]
public string Label { get; set; }
[XmlAttribute("min")]
public string Min { get; set; }
[XmlAttribute("max")]
public string Max { get; set; }
[XmlElement("option")]
public List<GeneralOptions> Items { get; } = new List<GeneralOptions>();
}
public class GeneralOptions
{
[XmlElement("id")]
public string Id { get; set; }
[XmlElement("name")]
public string Name { get; set; }
}
I suggest using xmltocsharp or anyother tools to convert the XML to C# Models within seconds... (eliminates all manual mistakes)
As mentioned by #canton7, another easy method is using Visual Studio: Edit -> Paste Special -> Paste XML As Classes
[XmlRoot(ElementName="option")]
public class Option {
[XmlElement(ElementName="id")]
public string Id { get; set; }
[XmlElement(ElementName="name")]
public string Name { get; set; }
}
[XmlRoot(ElementName="data")]
public class Data {
[XmlElement(ElementName="option")]
public List<Option> Option { get; set; }
[XmlAttribute(AttributeName="label")]
public string Label { get; set; }
[XmlAttribute(AttributeName="min")]
public string Min { get; set; }
[XmlAttribute(AttributeName="max")]
public string Max { get; set; }
}
[XmlRoot(ElementName="root")]
public class Root {
[XmlElement(ElementName="data")]
public Data Data { get; set; }
}
this is my first post here and as can you can imagine, i'm just a beginner in c#. So here's my question:
I'm deserializing a given xml to a custom class with XmlSerializer.
XML:
<epg>
<program start="20160404234500" stop="20160405001000" channel="281479340566592">
<eventid>604042345</eventid>
<titles>
<title>Schlauberger - Quizzen, was Spaß macht! (1)</title>
</titles>
<events>
<event>27. Schlauberger - Quizzen, was Spaß macht!</event>
</events>
<descriptions>
<description>27. Schlauberger - Quizzen, was Spaß macht!</description>
</descriptions>
</program>
<program start="20160504234500" stop="20160505001000" channel="281479340566587">
<eventid>604042348</eventid>
<title>Schlauberger - Quizzen, was Spaß macht! (2)</title>
<event>28. Schlauberger - Quizzen, was Spaß macht!</event>
<description>28. Schlauberger - Quizzen, was Spaß macht!</description>
</program>
Custom C# class:
public class Titles
{
[XmlElement("title")]
public string Title { get; set; }
}
public class SubTitles
{
[XmlElement("event")]
public string SubTitle { get; set; }
}
public class Descriptions
{
[XmlElement("description")]
public string Description { get; set; }
}
public class Program
{
[XmlElement("eventid")]
public string EventID { get; set; }
[XmlElement("titles")]
public Titles Titles { get; set; }
[XmlElement("events")]
public SubTitles SubTitles { get; set; }
[XmlElement("descriptions")]
public Descriptions Descriptions { get; set; }
[XmlAttribute("start")]
public string Start { get; set; }
[XmlAttribute("stop")]
public string Stop { get; set; }
[XmlAttribute("channel")]
public string Channel { get; set; }
[XmlElement("title")]
public string Title { get; set; }
[XmlElement("event")]
public string SubTitle { get; set; }
[XmlElement("description")]
public string Description { get; set; }
}
[XmlRoot(ElementName = "epg"), XmlType("epg")]
public class epg
{
[XmlElement("program")]
public List<Program> Program { get; set; }
}
No problem so far. But as you can see, because "title", "event" and "description" is sometimes nested in a majority and sometimes not, i can access the properties in my later code sometimes by a list and sometimes directly. This makes the code really inconvenient.
So is it somehow possible to ignore the majorities and always use the single nodes instead?
You could add some helper functions (or properties) to your Program class, e.g.:
public class Program
{
public Titles Titles { get; set; }
public string Title { get; set; }
public string GetTitle()
{
if (Titles != null)
{
return Titles.Title;
}
else
{
return Title;
}
}
}
I have the following code but unable to deserialize, can you see where I'm going wrong? It only catch the first record on the first array item.
[XmlRootAttribute("Booking")]
public class Reservation
{
[XmlArray("Included")]
[XmlArrayItem("Meals")]
public Meals[] Food { get; set; }
[XmlArrayItem("Drinks")]
public Drinks[] Drink { get; set; }
}
public class Meals
{
[XmlAttribute("Breakfast")]
public string Breakfast { get; set; }
[XmlAttribute("Lunch")]
public string Lunch { get; set; }
[XmlAttribute("Dinner")]
public string Dinner { get; set; }
}
public class Drinks
{
[XmlAttribute("Soft")]
public string Softs { get; set; }
[XmlAttribute("Beer")]
public string Beer { get; set; }
[XmlAttribute("Wine")]
public string Wine { get; set; }
}
Here's the associated XML
<?xml version="1.0" standalone="yes"?>
<Booking>
<Included>
<Meals
Breakfast="True"
Lunch="True"
Dinner="False">
</Meals>
<Drinks
Soft="True"
Beer="False"
Wine="False">
</Drinks>
</Included>
<Included>
<Meals
Breakfast="True"
Lunch="False"
Dinner="False">
</Meals>
<Drinks
Soft="True"
Beer="True"
Wine="True">
</Drinks>
</Included>
</Booking>
I'm a bit of a newbie so any help would be great, unfortunately after trawling through the many exmaples you already have online I still haven't been able to figure this out.
Use the following example and apply this syntax in ListItem array,
[XmlType("device_list")]
[Serializable]
public class DeviceList {
[XmlAttribute]
public string type { get; set; }
[XmlElement( "item" )]
public ListItem[] items { get; set; }
}
following link contains all the syntax & attributes
http://msdn.microsoft.com/en-us/library/2baksw0z.aspx
I see no obvious way your class structure could be matched to the XML document. The underlying organizations seem to be quite different.
The following class hierarchy could be easily deserialized from the XML document you provide (assuming your document covers the general case) :
[Serializable]
[XmlRoot("Booking")]
public class Booking : List<Included>
{
}
[Serializable]
public class Included
{
public Meals Meals { get; set; }
public Drinks Drinks { get; set; }
}
public class Meals
{
[XmlAttribute("Breakfast")]
public string Breakfast { get; set; }
[XmlAttribute("Lunch")]
public string Lunch { get; set; }
[XmlAttribute("Dinner")]
public string Dinner { get; set; }
}
public class Drinks
{
[XmlAttribute("Soft")]
public string Softs { get; set; }
[XmlAttribute("Beer")]
public string Beer { get; set; }
[XmlAttribute("Wine")]
public string Wine { get; set; }
}
Then, deserialization code would be : (serializedObject is the string containing your serialized object)
XmlSerializer ser = new XmlSerializer(typeof (string));
XmlReader reader = XmlTextReader.Create(new StringReader(serializedObject));
var myBooking = ser.Deserialize(reader) as Booking;