Here's my XML:
<Events>
<Event>
<content_id>6442452774</content_id>
<content_title>Title of the event</content_title>
<content_html>
<Date>2015-11-18</Date>
<EventType>Events</EventType>
<Description>
<p>this is an "event"</p>
</Description>
<Speakers>speaker1 LLC<br />speaker2<br />Jspeaker3</Speakers>
<Time>5:30 - 6:00pm Registration<br />6:00 - 7:00pm Panel Discussion<br />7:00 - 8:00pm Networking Reception</Time>
<Where></Where>
<RegistrationInfo>Please contact events#events.com to register for this event.</RegistrationInfo>
<Registration>false</Registration>
</content_html>
<date_created>2015-10-24T14:24:12.333</date_created>
<folder_id>262</folder_id>
<content_teaser>this is the content "can you display it."</content_teaser>
<content_text>text of the vent "more text" a lot of text here </content_text>
<end_date>2015-11-19T21:35:00</end_date>
<content_type>1</content_type>
<template_id>43</template_id>
<content_status>A</content_status>
</Event>
<Event>.... Other events </Event>
<Events>
and here's are my classes:
public class Serializable_Events
{
[XmlElement("Event")]
public List<Serializable_Event> EventList = new List<Serializable_Event>();
}
public class Serializable_Event
{
[XmlElement("content_id")]
public string content_id { get; set; }
[XmlElement("content_title")]
public string content_title { get; set; }
[XmlElement("content_html")]
public Serializable_Event_ContentHTML ContentHTML { get; set; }
[XmlText]
public string content_teaser { get; set; }
[XmlElement("content_text")]
public string content_text { get; set; }
}
public class Serializable_Event_ContentHTML
{
[XmlElement("Date")]
public string Date { get; set; }
[XmlElement("EventType")]
public string EventType { get; set; }
[XmlElement("Description")]
public string Description { get; set; }
[XmlElement("Speakers")]
public string Speakers { get; set; }
[XmlElement("Time")]
public string Time { get; set; }
[XmlElement("Where")]
public string Where { get; set; }
[XmlElement("RegistrationInfo")]
public string RegistrationInfo { get; set; }
[XmlElement("Registration")]
public bool Registration { get; set; }
//ignored html tags
[XmlIgnore]
public string p { get; set; }
[XmlIgnore]
public string br { get; set; }
[XmlIgnore]
public string a { get; set; }
}
Implementation:
XmlSerializer ser = new XmlSerializer(typeof(Serializable_Events));
var data = (Serializable_Events)ser.Deserialize(new StreamReader(#"events.xml"));
My problem is that some attributes are null and some are not (see the screenshot)
The ones that are null, like <Description> are due to malformed
XML.
You are storing HMTL directly in XML with text all over the place, and the serializer is not expecting that; further you are telling the serializer to ignore HTML tags using XmlIgnore which is intended for XML tags with properly formed XML. That's a wrong use of XmlIgnore
All XML which contains non-XML mark-up should be wrapped in CDATA sections; this will solve your problem. Further, you can remove all of the XmlIgnore code as well since it's not needed.
Your XML should look like this:
<Events>
<Event>
<content_id>6442452774</content_id>
<content_title>Title of the event</content_title>
<content_html>
<Date>2015-11-18</Date>
<EventType>Events</EventType>
<Description>
<![CDATA[<p>this is an ""event""</p>]]>
</Description>
<Speakers>
<![CDATA[speaker1 LLC<br />speaker2<br />Jspeaker3]]>
</Speakers>
<Time>
<![CDATA[5:30 - 6:00pm Registration<br />6:00 - 7:00pm Panel Discussion<br />7:00 - 8:00pm Networking Reception]]>
</Time>
<Where></Where>
<RegistrationInfo>
<![CDATA[Please contact <a href='mailto:events#events.com'>events#events.com</a> to register for this event.]]>
</RegistrationInfo>
<Registration>false</Registration>
</content_html>
<date_created>2015-10-24T14:24:12.333</date_created>
<folder_id>262</folder_id>
<content_teaser>this is the content 'can you display it.'</content_teaser>
<content_text>text of the vent 'more text' a lot of text here </content_text>
<end_date>2015-11-19T21:35:00</end_date>
<content_type>1</content_type>
<template_id>43</template_id>
<content_status>A</content_status>
</Event>
</Events>"
Related
I have created a REST Service which sends a response in XML. I have set the response format as XML and created the following Data Contracts:
[DataContract]
public class AuthorisationResult
{
[DataMember]
public string Status { get; set; }
[DataMember]
public Variable[] Variables { get; set; }
}
[DataContract]
public class Variable
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Type { get; set; }
}
This works ok however the output of the XML is not formatted as I need it. It is showing like this:
<Variables>
<Variable>
<Name>SomeName1</Name>
<Type>SomeType1</Type>
</Variable>
</Variables>
But I want to show it like this:
<Variables>
<Variable Name="SomeName1" Type="SomeType1"/>
</Variables>
Can anyone advise what I change to structure it how I want.
Just add XmlAttribute to the properties
[DataContract]
public class Variable
{
[DataMember, XmlAttribute]
public string Name { get; set; }
[DataMember, XmlAttribute]
public string Type { get; set; }
}
I have following xml
<result>
<key accessMask="4294967295" type="Account" expires="">
<rowset name="characters" key="characterID" columns="characterID,characterName,corporationID,corporationName,allianceID,allianceName,factionID,factionName">
<row characterID="123" characterName="Sefa 123" corporationID="456" corporationName="Signal Cartel" allianceID="159" allianceName="Scouts" factionID="0" factionName=""/>
<row characterID="1234" characterName="Sefa 1234" corporationID="987" corporationName="Havos" allianceID="753" allianceName="Unlimited" factionID="0" factionName=""/>
</rowset>
</key>
</result>
And i have following Schema setup for deserializing this output.
[XmlRoot("result")]
public class ApiKeyInfo
{
[XmlElement("key")]
public Key Key { get; set; }
}
public class Key
{
[XmlAttribute("accessMask")]
public long AccessMask { get; set; }
[XmlAttribute("type")]
public string Type { get; set; }
[XmlElement("rowset")]
public List<AccountCharacter> Characters { get; set; }
}
public class AccountCharacter
{
[XmlAttribute("characterId")]
public long Id { get; set; }
[XmlAttribute("characterName")]
public string Name { get; set; }
[XmlAttribute("corporationID")]
public long CorpId { get; set; }
[XmlAttribute("corporationName")]
public string CorpName { get; set; }
[XmlAttribute("allianceID")]
public long AllianceId { get; set; }
[XmlAttribute("allianceName")]
public string AllianceName { get; set; }
[XmlAttribute("factionID")]
public long FactionId { get; set; }
[XmlAttribute("factionName")]
public string FactionName { get; set; }
}
Problem is, i can't deserialize character informations. Characters list is always containing 0 elements inside.
This:
[XmlElement("rowset")]
public List<AccountCharacter> Characters { get; set; }
Implies that you'll have a bunch of rowset elements, e.g:
<rowset characterID="123" characterName="Sefa 123" ...
Try this instead:
[XmlArray("rowset")]
[XmlArrayItem("row")]
public List<AccountCharacter> Characters { get; set; }
A useful tip for these sort of deserialisation problems is to try the process in reverse: create an object and serialise it and see what the XML looks like. It will likely give you some indication as to where your problem is.
See this fiddle for a working demo, it prints both row name values to the console.
<TotalRecords ItineraryCount='1' >
<Recs ItineraryNumber="1" >
<Amount>516.6</Amount>
<TravelTime>940</TravelTime>
<FSegment>
<OutProperty>
<Segment No="1">
<Name>Ronald</Name>
<City>London</City>
<Country>United Kingdom</Country>
</Segment>
<Segment No="2">
<Name>Richard</Name>
<City>
London
</City>
<Country>United Kingdom</Country>
</Segment>
</OutProperty>
</FSegment>
</Recs>
</TotalRecords >
I am serializing xml to object of TotalRecords Class. It works fine when there are more than one segment in the OutProperty but in case of one segment it doesn't serialize into list property.
I have also tried with [XmlArray("")] and [XMlArrayItem("")] but it doesn't work. Anyone have idea?
public class TotalRecords
{
public Recs recs { get; set; }
public string ItineraryCount { get; set; }
}
public partial class Recs
{
public string amountField { get; set; }
public string travelTimeField { get; set; }
public FSegment fSegmentField { get; set; }
public string itineraryNumberField { get; set; }
}
public class FSegment
{
public List<Segment> OutProperty {get;set;}
}
public class Segment
{
public string nameField { get; set; }
public string cityField { get; set; }
public string countryField { get; set; }
}
Try to use the following for your Classes and their Properties:
[DataContract]
public class Contact
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
}
Hacking like this helps in many cases, perhaps in your too (converting List to array):
public class FSegment
{
[XmlIgnore]
public List<Segment> OutProperty {get;set;}
[XmlArray("OutProperty");
public Segment[] _OutProperty
{
get { return OutProperty.ToArray(); }
set { OutProperty = new List<Segment>(value); }
}
}
I am not exactly sure how your provided class definition worked previously without any XML attribute/element definitions since your variable names are not the same as the XML identifiers, meaning that the serialization wouldn't populate the properties that it couldn't find a name for.
Nether the less, the main issue here is that you are trying to put a list into a normal property.
From the XML provided, OutProperty is a single sub element of FSegment and Segment is an array of sub elements of OutProperty, but in your provided code, you tried to make Segment an array sub element of FSegment.
The correct structure of the class definition should be as follows (also including the XML definitions)
[System.Xml.Serialization.XmlRoot(ElementName="TotalRecords")]
public class TotalRecords
{
[System.Xml.Serialization.XmlElement(ElementName="Recs")]
public Recs recs { get; set; }
[System.Xml.Serialization.XmlAttribute(AttributeName = "ItineraryCount")]
public string ItineraryCount { get; set; }
}
public partial class Recs
{
[System.Xml.Serialization.XmlElement(ElementName = "Amount")]
public string amountField { get; set; }
[System.Xml.Serialization.XmlElement(ElementName = "TravelTime")]
public string travelTimeField { get; set; }
[System.Xml.Serialization.XmlElement(ElementName = "FSegment")]
public FSegment fSegmentField { get; set; }
[System.Xml.Serialization.XmlAttribute(AttributeName = "ItineraryNumber")]
public string itineraryNumberField { get; set; }
}
public class FSegment
{
[System.Xml.Serialization.XmlElement(ElementName = "OutProperty")]
public SegmentList OutProperty { get; set; }
}
public class SegmentList
{
[System.Xml.Serialization.XmlElement(ElementName = "Segment")]
public List<Segment> segmentField { get; set; }
}
public class Segment
{
[System.Xml.Serialization.XmlElement(ElementName = "Name")]
public string nameField { get; set; }
[System.Xml.Serialization.XmlElement(ElementName = "City")]
public string cityField { get; set; }
[System.Xml.Serialization.XmlElement(ElementName = "Country")]
public string countryField { get; set; }
[System.Xml.Serialization.XmlAttribute(AttributeName = "No")]
public int segmentNoField { get; set; }
}
Please note that in the above structure, Segment is a list object under the OutProperty object, which resides under the FSegment object.
Using this class structure to load your XML produces the (assumed) correct data in the created objects.
Using the XML definitions allows you to decouple the actual names of class properties from what they are called in the XML data. This allows you to changes the one or the other without affecting the other one, which is useful when you don't control the creation of the XML data.
If you don't want all the XML definitions in your code, change the names of the classes so that you can name your properties the same as what they are called in the XML file. That will allow you couple everything directly
I want to covert to string into object with value. I mean let's say i have string that has XML code inside like:
string response = #"<?xml version=""1.0"" encoding=""utf-8""?>
<Response>
<ResultCode>0</ResultCode>
<ResultMessage>success</ResultMessage>
<Body>
<Rooms>
<Room>
<RoomID>room1#nxdev.com</RoomID>
<RoomName>White Room</RoomName>
<Capacity>10</Capicity>
<Equipments>Beam Projector, VTR</Equipments>
<Reservations>
<Reservation>
<StartDT> 2014-02-18 14:00</StartDT>
<EndDT>2014-02-18 15:00</EndDT>
<UserName>Jhon</UserName>
<Subject>Project Meeting</Subject>
<Reservation>
</Reservatoins>
</Room>
</Rooms>
</Body>
</Response>"
I have a Class that has all the properties which mentioned in Xml like
[XmlRoot("Response")]
public class Response
{
string ResultCode {get; set; }
string ResutlMessage { get; set; }
}
public class RoomListResponse : Response
{
List<Room> rooms { get; set; }
}
public class Room
{
[XmlElement("RoomID")]
string RoomID { get; set; }
[XmlElement("RoomName")]
string RoomName { get; set; }
[XmlElement("Capacity")]
string Capacity { get; set; }
[XmlElement("Equipments")]
string Equipments { get; set; }
List<Reservation> Reservations;
}
public class Reservations
{
[XmlElement("StartDT")]
string StartDT { get; set; }
[XmlElement("EndDT")]
string EndDT { get; set; }
[XmlElement("UserName")]
string UserName { get; set; }
[XmlElement("Subject")]
string Subject { get; set; }
}
How can I set all the values in RoomListResponse object without string parsing? I have tried it with serialization but it gives me some problem in windows 8.1 app store project due to limitation in API.
Is there any way to get it sorted?
Serialization is the only way.
In your case you might want to try replacing the
List<Reservation> Reservations;
by
[XmlElement("Reservations")]
Reservation [] Reservations;
and then use the XmlSerializer
I have a fixed, valid XML document. I'm trying to deserialize it in order to get an object hierarchy. However there's an exception being thrown.
This is my XML document:
<ROWSET>
<ROW>
<LOT>LOT1234</LOT>
<DATE_TRANS>2012-05-20</DATE_TRANS>
<NUMERO_AA227>AA227_001</NUMERO_AA227>
<NUMERO_ETUI>ETUI_001</NUMERO_ETUI>
<IDENTITE_BOITE_1>Boite1_1</IDENTITE_BOITE_1>
<IDENTITE_BOITE_2>Boite1_2</IDENTITE_BOITE_2>
<IDENTITE_BOITE_3>Boite1_3</IDENTITE_BOITE_3>
<IDENTITE_BOITE_4>Boite1_5</IDENTITE_BOITE_4>
<IDENTITE_BOITE_5>Boite1_5</IDENTITE_BOITE_5>
</ROW>
<ROW>
<LOT>LOT5678</LOT>
<DATE_TRANS>2012-05-20</DATE_TRANS>
<NUMERO_AA227>AA227_001</NUMERO_AA227>
<NUMERO_ETUI>ETUI_001</NUMERO_ETUI>
<IDENTITE_BOITE_1>Boite1_1</IDENTITE_BOITE_1>
<IDENTITE_BOITE_2>Boite1_2</IDENTITE_BOITE_2>
<IDENTITE_BOITE_3>Boite1_3</IDENTITE_BOITE_3>
<IDENTITE_BOITE_4>Boite1_5</IDENTITE_BOITE_4>
<IDENTITE_BOITE_5>Boite1_5</IDENTITE_BOITE_5>
</ROW>
</ROWSET>
And this is my object model:
[Serializable]
[System.Xml.Serialization.XmlRoot("DTOFournitureListeImporter")]
public class DTOFournitureListeImporter
{
[XmlArray("ROWSET")]
[XmlArrayItem("ROW", typeof(DTOFournitureImporter))]
public DTOFournitureImporter[] dtoFournitureImporter { get; set; }
}
[Serializable]
public class DTOFournitureImporter
{
[System.Xml.Serialization.XmlElement("lot")]
public string lot { get; set; }
[System.Xml.Serialization.XmlElement("date_trans")]
public DateTime date_trans { get; set; }
[System.Xml.Serialization.XmlElement("numero_aa227")]
public string numero_aa227 { get; set; }
[System.Xml.Serialization.XmlElement("numero_etui")]
public string numero_etui { get; set; }
[System.Xml.Serialization.XmlElement("identite_boite_1")]
public string identite_boite_1 { get; set; }
[System.Xml.Serialization.XmlElement("identite_boite_2")]
public string identite_boite_2 { get; set; }
[System.Xml.Serialization.XmlElement("identite_boite_3")]
public string identite_boite_3 { get; set; }
[System.Xml.Serialization.XmlElement("identite_boite_4")]
public string identite_boite_4 { get; set; }
[System.Xml.Serialization.XmlElement("identite_boite_5")]
public string identite_boite_5 { get; set; }
}
How I deserialize:
XmlSerializer serializer = new XmlSerializer(typeof(DTOFournitureListeImporter));
TextReader textReader = new StreamReader(model.cheminFichierXML);
DTOFournitureListeImporter dTOFournitureListeImporter = (DTOFournitureListeImporter)serializer.Deserialize(textReader);
textReader.Close();
And the error:
There is an error in XML document (2, 2). -
System.InvalidOperationException: was not expected.
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDTOFournitureListeImporter.Read4_DTOFournitureListeImporter()
The problem could be that all the tags in the XML file are in capital letters, but the attributes in your class suggest they should be in small letters.
Also, you're saying in the attributes that the XML root is DTOFournitureListeImporter, which is not the case. The XML root is ROWSET.
So all in all: The structure you're trying to create does not match the XML file.