2

Is it possible to deserialize the following XML:

<MyObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyObject>

into this object:

public class MyObject {
    public string Test { get; set; }
    public string Something { get; set; }
}

with this as expected output (this fails at the moment with XmlException: Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content. Line 1, position 50.)

[TestMethod]
public void TestDeserialization()
{
    var s = "<MyObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyObject>";

    var o = s.DeSerialize<MyObject>();
    Assert.AreEqual("Hi hello", o.Test);
    Assert.AreEqual("<Else><With><SubItems count='5'>hello world</SubItems></With></Else>", o.Something);
}

public static class Xml
{
    public static T DeSerialize<T>(this string xml) where T : new()
    {
        if (String.IsNullOrEmpty(xml))
        {
            return new T();
        }
        var xmlSer = new XmlSerializer(typeof(T));
        using (var stream = new StringReader(xml))
            return (T)xmlSer.Deserialize(stream);
    }
}
1
  • Yes, it is possible. You say your code fails - why? You also don't show your code for DeSerialize so how can we possibly help? Commented Oct 23, 2014 at 9:59

1 Answer 1

4

One option could be implementing IXmlSerializable so you manually read the inner Xml into the Something property:

public class MyObject: IXmlSerializable 
{
    public string Test { get; set; }
    public string Something { get; set; }

    public System.Xml.Schema.XmlSchema GetSchema() { return null; }

    public void ReadXml(System.Xml.XmlReader reader)
    {       
        if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "MyObject")
        {           
            Test = reader["Test"];
            if (reader.ReadToDescendant("Something"))
            {
                Something = reader.ReadInnerXml();
            }
        }                   
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        throw new NotImplementedException();
    }   
}

public static class Program
{
    public static void Main()
    {   
        var myObjectXmlString = "<MyObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyObject>";    
        var myObject =(MyObject) new XmlSerializer(typeof(MyObject)).Deserialize(new StringReader(myObjectXmlString));
        Console.WriteLine(myObject.Something);
    }
}

Another option could be converting Something into a property of type XmlElement so the inner random piece of Xml will be serialized as Xml instead of a string (You could still retrieve it as string by getting its OuterXml):

public class MyOtherObject 
{
    public string Test { get; set; }    
    public XmlElement Something { get; set; }
    public string SomethingString
    {
        get { return Something.OuterXml; }
    }
}

public static class Program
{
    public static void Main()
    {   
        var otherObjectXmlString = "<MyOtherObject><Test>Hi hello</Test><Something><Else><With><SubItems count='5'>hello world</SubItems></With></Else></Something></MyOtherObject>";   
        var otherObject =(MyOtherObject) new XmlSerializer(typeof(MyOtherObject)).Deserialize(new StringReader(otherObjectXmlString));
        Console.WriteLine(otherObject.SomethingString);             
    }
}

I have created this fiddle so you can give them a try.

Sign up to request clarification or add additional context in comments.

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.