Solved

DeSerialization - Element child nodes to string

Posted on 2011-09-07
5
1,204 Views
Last Modified: 2012-05-12
Hello Experts,

Assume I want to deserialize the following XML:

<ROOT>
<STATUS>101</STATUS>
<PAYLOAD>
<PERSON>
<FIRSTNAME>xxx</FIRSTNAME>
<....>xxx</....>
</PERSON>
</PAYLOAD>
</ROOT>

Open in new window


I would like to deserialize this xml, but let the payload element outerxml (element + childnodes) to be stored as a string in the PayLoad property.

    [XmlRoot(ElementName="ROOT")]
    public class Example
    {
        private string status;
        private string payLoad;

        [XmlElement(ElementName = "PAYLOAD")]
        public string PayLoad
        {
            get { return payLoad; }
            set { payLoad= value.}
        }
        [XmlElement(ElementName = "STATUS")]
        public string Status
        {
            get { return status; }
            set { status = value; }
        }

    }

Open in new window


Example use:

Example MyExample = serializer.Deserialize(xmlstring);

Console.WriteLine(MyExample.PayLoad);

//Writes:
//<PAYLOAD><PERSON><FIRSTNAME>xxx</FIRSTNAME><....>xxx</....></PERSON></PAYLOAD>

Open in new window


Is this possible?

Thank you,
amr-it
0
Comment
Question by:amr-it
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 36496705
You could do something like this:
XmlSerializer MyExample = new XmlSerializer(typeof(Example));

MyExample.UnknownElement += new XmlElementEventHandler(deserializer_UnknownElement);

Example MyExample = serializer.Deserialize(xmlstring) AS Example;

...

static void deserializer_UnknownElement(object sender, XmlElementEventArgs e)
{
    Example obj = e.ObjectBeingDeserialized as Example;

    if (e.Element.Name == "PAYLOAD")
    {
        obj.PayLoad = e.Element.OuterXml;
    }
}

Open in new window

0
 
LVL 1

Author Comment

by:amr-it
ID: 36500900
Thank you kaufmed for your comment.
I forgot to mention that my serializer and deserializer methods are located in a helper class and are designed to be generic (handling many different types), meaning if possible, I don't want to cast to the Example type. I got it to work doing something very similair to what you have proposed and I would assume that the above would work.

But, is there any way to define this in the class design so that the deserializer directly knows how to handle it?
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 36502347
You could define a method in your class which takes in a delegate parameter and then assign the delegate as the handler for the event mentioned above. The signature of the delegate would need to match the signature as demonstrated above. Then each delegate would take care of managing the types it works with.

I don't know your specific code, but here is a demonstration of what I'm talking about:
using System;
using System.Xml;
using System.Xml.Serialization;

namespace _27295319
{
    class Program
    {
        /// <summary>
        /// Entry point for application.
        /// </summary>
        /// <param name="args">The args.</param>
        /// \date 9/8/2011 8:41 AM
        static void Main(string[] args)
        {
            SerializerClass deserailzer = new SerializerClass(typeof(Example));

            deserailzer.SetUnknownElementHandler(deserializer_UnknownElement);
            Example obj = deserailzer.Deserialize(System.IO.File.OpenRead("input.xml")) as Example;
        }

        /// <summary>
        /// The handler that will be attached to the SerializerClass' internal XmlSerializer.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Xml.Serialization.XmlElementEventArgs"/> instance containing the event data.</param>
        /// \date 9/8/2011 8:42 AM
        static void deserializer_UnknownElement(object sender, XmlElementEventArgs e)
        {
            Example obj = e.ObjectBeingDeserialized as Example;

            if (obj != null && e.Element.Name == "PAYLOAD")
            {
                obj.PayLoad = e.Element.OuterXml;
            }
        }
    }

    /// <summary>
    /// Example class which handles deserialization of an object.
    /// </summary>
    /// \author Kenneth Kaufmann
    /// \date 9/8/2011 8:41 AM
    public class SerializerClass
    {
        private XmlSerializer deserializer;
        private XmlElementEventHandler unknownElementHandler;   // Keep track of the handler that was added so we can remove
                                                                //  it later if we need to

        /// <summary>
        /// Initializes a new instance of the <see cref="SerializerClass"/> class.
        /// </summary>
        /// <param name="typeToSerialize">The type to serialize.</param>
        /// \date 9/8/2011 8:40 AM
        public SerializerClass(Type typeToSerialize)
        {
            deserializer = new XmlSerializer(typeToSerialize);
        }

        /// <summary>
        /// Attaches a handler for the UnknownElementHandler.
        /// </summary>
        /// <param name="handler"></param>
        public void SetUnknownElementHandler(XmlElementEventHandler handler)
        {
            if (unknownElementHandler != null) deserializer.UnknownElement -= unknownElementHandler;

            unknownElementHandler = handler;
            deserializer.UnknownElement += unknownElementHandler;
        }

        /// <summary>
        /// Deserializes the specified source data.
        /// </summary>
        /// <param name="sourceData">The source data.</param>
        /// <returns></returns>
        /// \date 9/8/2011 8:41 AM
        public object Deserialize(System.IO.Stream sourceData)
        {
            return deserializer.Deserialize(sourceData);
        }
    }

    [XmlRoot(ElementName = "ROOT")]
    public class Example
    {
        private string status;
        private string payLoad;

        public string PayLoad
        {
            get { return payLoad; }
            set { payLoad = value; }
        }

        [XmlElement(ElementName = "STATUS")]
        public string Status
        {
            get { return status; }
            set { status = value; }
        }
    }
}

Open in new window

0
 
LVL 1

Assisted Solution

by:amr-it
amr-it earned 0 total points
ID: 36528798
Thank you for your response. I ended up with a better solution, creating a generic class so it can be used for serialization.

    [XmlRoot(ElementName="ROOT")]
    public class Example<T> where T : new()
    {
        private string status;
        private T apiPayLoad = new T();

        [XmlElement(ElementName="APIPAYLOAD")]
        public T APIPayLoad
        {
            get { return apiPayLoad; }
            set { apiPayLoad = value; }
        }

        [XmlElement(ElementName = "STATUS")]
        public string Status
        {
            get { return status; }
            set { status = value; }
        }

    }

Open in new window



Usage:

        public static T DeserializeFromXml<T>(string xml)
        {
            T result;
            XmlSerializer ser = new XmlSerializer(typeof(T));
            ser.UnknownElement += new XmlElementEventHandler(ser_UnknownElement);
            using (TextReader tr = new StringReader(xml))
            {
                result = (T)ser.Deserialize(tr);
            }
            return result;
        }

Open in new window


Example<Person> PersonPayLoad = DeserializeFromXML<Example<Person>>(xml);

Open in new window

0
 
LVL 1

Author Closing Comment

by:amr-it
ID: 36555754
Comment for accepting own solution + expert:
Hopefully this generic solution also can be used for someone.
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question