Reputation: 19
I'm deserialization the results of a request that has the same tag repeated at multiple levels, I have it working but to do so I'm changing the format of the XML before attempting to deserialize it.
I'm not able to edit the source of the XML to change it to only have Diary
at one level.
Is there a way to adjust my XML attributes to handle the deserialization without needing to adjust the response?
XML Response
<?xml version="1.0" ?>
<Root>
<DiaryDetails>
<Diary>
<Diary created_user="value1" created_date="value2" long_text="value3" short_text="value4" entry_type="value5" >Value6</Diary>
</Diary>
<Diary>
<Diary created_user="value7" created_date="value8" long_text="value9" short_text="value10" entry_type="value11" >Value12</Diary>
</Diary>
</DiaryDetails>
</Root>
Class definition
[XmlRoot("DiaryDetails")]
public class Diaries : List<Diary> { }
[XmlRoot("Diary")]
public class Diary
{
[XmlAttribute("created_user")]
public string CreatedBy { get; set; }
[XmlAttribute("created_date")]
public string CreatedDate { get; set; }
[XmlAttribute("long_text")]
public string LongText { get; set; }
[XmlAttribute("short_text")]
public string ShortText { get; set; }
[XmlAttribute("entry_type")]
public string Type { get; set; }
}
Deserialization Method
internal T DeserilaiseObject<T>(string response)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
T DeserilaisedObject;
using (TextReader reader = new StringReader(response))
{
DeserilaisedObject = (T)serializer.Deserialize(reader);
}
return DeserilaisedObject;
}
I'm currently handling this with a string replace:
response = response.Replace("<Diary><Diary", "<Diary").Replace("</Diary></Diary>", "</Diary>");
Upvotes: 0
Views: 140
Reputation: 10296
Assuming that you are only interested at the attributed Diary
elements at the second nesting level you could do this:
// load your xml into a document
var doc = new XmlDocument();
doc.Load("your_xml_file.xml");
// extract the interesting nodes using xpath
var nodes = doc.SelectNodes("//Diary/Diary");
// deserialize the filtered NodeList (yes it's that clunky)
var serializer = new XmlSerializer(typeof(Diary));
var diaries = nodes.Cast<XmlNode>().Select(x => serializer.Deserialize(new XmlNodeReader(x))).Cast<Diary>().ToArray();
Upvotes: 0
Reputation: 34421
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication40
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Root));
Root root = (Root)serializer.Deserialize(reader);
}
}
[XmlRoot("Root")]
public class Root
{
[XmlArray("DiaryDetails")]
[XmlArrayItem("Diary")]
public List<DiaryMain> diaries { get; set; }
}
public class DiaryMain
{
public Diary Diary { get; set; }
}
[XmlRoot("Diary")]
public class Diary
{
[XmlAttribute("created_user")]
public string CreatedBy { get; set; }
[XmlAttribute("created_date")]
public string CreatedDate { get; set; }
[XmlAttribute("long_text")]
public string LongText { get; set; }
[XmlAttribute("short_text")]
public string ShortText { get; set; }
[XmlAttribute("entry_type")]
public string Type { get; set; }
}
}
Upvotes: 1