0

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>");

2 Answers 2

1

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; }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.