Reputation: 21
I want to serialize a nested object so that its properties are at the same level as the parent object, (ie, NOT in a nested tag). Specifically: I have a C# object:
[XmlRoot(ElementName="Root")]
public class TopLevel
{
public string topLevelProperty;
public NestedObject nestedObj;
}
public class NestedObject
{
string propetyOnNestedObject;
}
and I want XML like:
<root>
<topLevelProperty>...</topLevelProperty>
<propertyOnNestedObject>...</propertyOnNestedObject>
<!--NOTE: propertyOnNestedObject would normally be inside a "<nested>" tag
but I'm trying to avoid that here-->
</root>
Is that possible?
Upvotes: 0
Views: 3216
Reputation: 16296
You can do this with the YAXLib XML Serialization library easily:
//[XmlRoot(ElementName = "Root")]
[YAXSerializeAs("Root")]
public class TopLevel
{
public string topLevelProperty { get; set; }
public NestedObject nestedObj { get; set; }
}
public class NestedObject
{
[YAXElementFor("..")]
string propetyOnNestedObject { get; set; }
}
Note how YAXElementFor("..")
attribute directs the location of serialization to the parent element. (".."
looks likes parent folder in file-system paths).
Upvotes: 1
Reputation: 62564
As a case you can expose a nested proeprty accessor but this would make TopLevel object slightly complex. So as a case you can introduce a separate serializable wrapper to decouple such special-case wrapper from the business object itself.
[XmlRoot(ElementName="Root")]
public class TopLevel
{
public string topLevelProperty;
[XmlIgnore]
public NestedObject nestedObj;
[XmlElement("NestedProperty")]
public string NestedPropertyAccessor
{
get
{
return nestedObj.NestedProperty;
}
// set
}
}
OR Separate it if you need decouple serializable object from business model so you do not need complicate business object itself by specially exposed properties just to fit serialization format:
public class TopLevelSerializableWrapper
{
public TopLevelSerializableWrapper(TopLevel businessObject)
{
}
// TODO: expose all proeprties which need to serialized
}
Upvotes: 1
Reputation: 1124
You need to implement the IXmlSerializable
Interface to override the default behaviour
[XmlRoot(ElementName = "Root")]
public class TopLevel : IXmlSerializable
{
public string topLevelProperty;
public NestedObject nestedObj;
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
//...
}
public void WriteXml(XmlWriter writer)
{
writer.WriteElementString("topLevelProperty", topLevelProperty);
writer.WriteElementString("propertyOnNestedObject", nestedObj.propetyOnNestedObject);
}
}
There is also a good post at CodeProject about how to implement the interface correctly: http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly
Upvotes: 1