c# - Nested classes deserialized from flat XML -
if have xml file looks like
<foo> <name>some data</name> <bar_data>other data</bar_data> <bar_moredata>more data</bar_moredata> </foo>
and want turn in c# class looks like
public class foo { public string name {get; set; } public bar bar { get; set; } } public class bar { public string data { get; set; } public string moredata { get; set; } }
is there way accomplish simple data annotations (xmlroot
, xmlelement
, etc.) or option implement ixmlserializable
?
edit: note, ever need deserialize data. xml 3rd party source , not need ever serialize foo
in xml (if makes easier).
one option use xmlanyelementattribute below:
public class foo { public string name { get; set; } public bar bar { get; set; } [xmlanyelementattribute] public xmlelement[] barelements { { return null; } set { bar = new bar(); var bartype = bar.gettype(); foreach (var prop in value) bartype.getproperty(prop.name.substring(4)).setvalue(bar, prop.innertext); } } } public class bar { public string data { get; set; } public string moredata { get; set; } }
when xmlserializer not recognize element adds property of type xmlelement[] marked xmlanyelementattribute. can process bar properties. used reflection there show idea.
another option deserialize twice , connect bar foo:
public class foo { public string name { get; set; } public bar bar { get; set; } } [xmlroot("foo")] public class bar { [xmlelement("bar_data")] public string data { get; set; } [xmlelement("bar_moredata")] public string moredata { get; set; } } var foo = (foo) new xmlserializer(typeof (foo)).deserialize(...); var bar = (bar) new xmlserializer(typeof (bar)).deserialize(...); foo.bar = bar
yet option no intrusion classes being deserialized:
public class foo { public string name { get; set; } public bar bar { get; set; } } public class bar { public string data { get; set; } public string moredata { get; set; } } var fooserializer = new xmlserializer(typeof (foo)); fooserializer.unknownelement += (sender, e) => { var foo = (foo) e.objectbeingdeserialized; if(foo.bar == null) foo.bar = new bar(); var propname = e.element.name.substring(4); typeof(bar).getproperty(propname).setvalue(foo.bar, e.element.innertext); }; var fooinstance = fooserializer.deserialize(...);
and if double deserialization or reflection problematic performance wise, create surrogate proxy class:
[xmlroot("foo")] public class foosurrogate { public string name { get; set; } public string bar_data { get; set; } public string bar_moredata { get; set; } public foo tofoo() { return new foo { name = name, bar = new bar { data = bar_data, moredata = bar_moredata } }; } } var seializer = new xmlserializer(typeof (foosurrogate)); var foo = ((foosurrogate) seializer.deserialize(...)).tofoo();
Comments
Post a Comment