private void WriteElement(object o, ElementAccessor element, string arrayName, bool writeAccessor, XmlMapping parentMapping = null)
{
string name = writeAccessor ? element.Name : element.Mapping.TypeName;
string ns = element.Any && element.Name.Length == 0 ? null : (element.Form == XmlSchemaForm.Qualified ? (writeAccessor ? element.Namespace : element.Mapping.Namespace) : "");
if (element.Mapping is NullableMapping)
{
if (o != null)
{
ElementAccessor e = element.Clone();
e.Mapping = ((NullableMapping)element.Mapping).BaseMapping;
WriteElement(o, e, arrayName, writeAccessor);
}
else if (element.IsNullable)
{
WriteNullTagLiteral(element.Name, ns);
}
}
else if (element.Mapping is ArrayMapping)
{
var mapping = (ArrayMapping)element.Mapping;
if (mapping.IsSoap)
{
throw new PlatformNotSupportedException();
}
if (element.IsNullable && o == null)
{
WriteNullTagLiteral(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : "");
}
else
{
if (element.IsUnbounded)
{
TypeDesc arrayTypeDesc = mapping.TypeDesc.CreateArrayTypeDesc();
var enumerable = (IEnumerable)o;
foreach (var e in enumerable)
{
element.IsUnbounded = false;
WriteElement(e, element, arrayName, writeAccessor);
element.IsUnbounded = true;
}
}
else
{
if (o != null)
{
WriteStartElement(name, ns, false);
WriteArrayItems(mapping.ElementsSortedByDerivation, null, null, mapping.TypeDesc, o);
WriteEndElement();
}
}
}
}
else if (element.Mapping is EnumMapping)
{
if (element.Mapping.IsSoap)
{
throw new PlatformNotSupportedException();
}
else
{
WritePrimitive(WritePrimitiveMethodRequirement.WriteElementString, name, ns, element.Default, o, element.Mapping, false, true, element.IsNullable);
}
}
else if (element.Mapping is PrimitiveMapping)
{
PrimitiveMapping mapping = (PrimitiveMapping)element.Mapping;
if (mapping.TypeDesc == QnameTypeDesc)
{
WriteQualifiedNameElement(name, ns, element.Default, (XmlQualifiedName)o, element.IsNullable, mapping.IsSoap, mapping);
}
else
{
if (mapping.IsSoap)
{
throw new PlatformNotSupportedException();
}
WritePrimitiveMethodRequirement suffixRaw = mapping.TypeDesc.XmlEncodingNotRequired ? WritePrimitiveMethodRequirement.Raw : WritePrimitiveMethodRequirement.None;
WritePrimitive(element.IsNullable
? WritePrimitiveMethodRequirement.WriteNullableStringLiteral | suffixRaw
: WritePrimitiveMethodRequirement.WriteElementString | suffixRaw,
name, ns, element.Default, o, mapping, mapping.IsSoap, true, element.IsNullable);
}
}
else if (element.Mapping is StructMapping)
{
var mapping = (StructMapping)element.Mapping;
if (mapping.IsSoap)
{
throw new PlatformNotSupportedException();
}
WriteStructMethod(mapping, name, ns, o, mapping.TypeDesc.IsNullable, needType: false, parentMapping: parentMapping);
}
else if (element.Mapping is SpecialMapping)
{
if (element.Mapping is SerializableMapping)
{
WriteSerializable((IXmlSerializable)o, name, ns, element.IsNullable, !element.Any);
}
else
{
// XmlNode, XmlElement
var node = o as XmlNode;
if (node != null)
{
WriteElementLiteral(node, name, ns, element.IsNullable, element.Any);
}
else
{
throw CreateInvalidAnyTypeException(o);
}
}
}
else
{
throw new InvalidOperationException(SR.XmlInternalError);
}
}