I am having huge problems with XML serialization. I have two classes, both need to be serializeable. In the inherited class, I would like to change the serialization behavior, so that a string property gets serialized as complex type.
public class Animal
{
[XmlElement(ElementName = "NAME")]
public string Name { get; set; }
public virtual bool ShouldSerializeName() { return true; }
}
public class Cat : Animal
{
public override bool ShouldSerializeName() { return false; }
[XmlElement(ElementName = "NAME")]
public NameAndType Name2 { get; set; }
}
public class NameAndType
{
public string Name { get; set; }
public string Type { get; set; }
}
...
var cat = new Cat {Name2 = new NameAndType {Name = "LittleCat"}};
new XmlSerializer(typeof(Cat)).Serialize(Console.Out, cat);
I have tried different approaches, but I didn't find a way to change how the NAME
element get's serialized.
With the example above, I get the error message:
The XML element 'NAME' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.
You're specifying two different XML elements with the same name on the same graph level, which is not allowed.
I will offer a solution, but it involves concatenating type and name for the Cat class serialization. If it is not imperative to serialize that NameAndType class, then go on: On Animal, set Name to be virtual; On Cat, set XmlIgnore on Name2. Then override Name and return both properties of Name2 the way you fancy.
If you really need to serialize that class as it is, then I'm afraid you'll have to so it with a different elementName.
Edit: Sample code:
The reason you get the error is that, during
XmlSerializer
code generation, the code generator doesn't understand that the two potentialNAME
elements onCat
will never be simultaneously serialized, so throws the exception.Instead, you can apply
XmlAnyElementAttribute
to a virtual property returning anXElement
, then manually create and return an appropriateXElement
for the name for each class in the hierarchy:Using the extension methods:
Which, for a
List<Animal>
, produces XML like this: