private XElement MakeCollectionElement(
XElement insertionLocation, XName elementName, object elementValue,
YAXCollectionAttribute collectionAttrInst, string format)
{
if (elementValue == null)
return new XElement(elementName);
if (!(elementValue is IEnumerable))
throw new ArgumentException("elementValue must be an IEnumerable");
// serialize other non-collection members
var ser = NewInternalSerializer(elementValue.GetType(), elementName.Namespace, insertionLocation);
XElement elemToAdd = ser.SerializeBase(elementValue, elementName);
FinalizeNewSerializer(ser, true);
// now iterate through collection members
var collectionInst = elementValue as IEnumerable;
var serType = YAXCollectionSerializationTypes.Recursive;
string seperator = string.Empty;
XName eachElementName = null;
if (collectionAttrInst != null)
{
serType = collectionAttrInst.SerializationType;
seperator = collectionAttrInst.SeparateBy;
if (collectionAttrInst.EachElementName != null)
{
eachElementName = StringUtils.RefineSingleElement(collectionAttrInst.EachElementName);
if (eachElementName.Namespace.IsEmpty())
RegisterNamespace(eachElementName.Namespace, null);
eachElementName = eachElementName.OverrideNsIfEmpty(elementName.Namespace.IfEmptyThen(TypeNamespace).IfEmptyThenNone());
}
}
Type colItemType = ReflectionUtils.GetCollectionItemType(elementValue.GetType());
UdtWrapper colItemsUdt = TypeWrappersPool.Pool.GetTypeWrapper(colItemType, this);
if (serType == YAXCollectionSerializationTypes.Serially && !ReflectionUtils.IsBasicType(colItemType))
serType = YAXCollectionSerializationTypes.Recursive;
if (serType == YAXCollectionSerializationTypes.Serially && elemToAdd.IsEmpty)
{
var sb = new StringBuilder();
bool isFirst = true;
object objToAdd = null;
foreach (object obj in collectionInst)
{
if (colItemsUdt.IsEnum)
objToAdd = colItemsUdt.EnumWrapper.GetAlias(obj);
else if (format != null)
objToAdd = ReflectionUtils.TryFormatObject(obj, format);
else
objToAdd = obj;
if (isFirst)
{
sb.Append(objToAdd.ToXmlValue());
isFirst = false;
}
else
{
sb.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}", seperator, objToAdd);
}
}
bool alreadyAdded = false;
elemToAdd = MakeBaseElement(insertionLocation, elementName, sb.ToString(), out alreadyAdded);
if (alreadyAdded)
elemToAdd = null;
}
else
{
//var elem = new XElement(elementName, null);
object objToAdd = null;
foreach (object obj in collectionInst)
{
objToAdd = (format == null) ? obj : ReflectionUtils.TryFormatObject(obj, format);
var curElemName = eachElementName;
if(curElemName == null)
{
curElemName = colItemsUdt.Alias;
}
XElement itemElem = AddObjectToElement(elemToAdd, curElemName.OverrideNsIfEmpty(elementName.Namespace), objToAdd);
if (obj != null && !obj.GetType().EqualsOrIsNullableOf(colItemType))
{
itemElem.AddAttributeNamespaceSafe(m_yaxLibNamespaceUri + m_trueTypeAttrName, obj.GetType().FullName, m_documentDefaultNamespace);
if (itemElem.Parent == null) // i.e., it has been removed, e.g., because all its members have been serialized outside the element
elemToAdd.Add(itemElem); // return it back, or undelete this item
RegisterYaxLibNamespace();
}
}
}
int[] arrayDims = ReflectionUtils.GetArrayDimensions(elementValue);
if (arrayDims != null && arrayDims.Length > 1)
{
elemToAdd.AddAttributeNamespaceSafe(m_yaxLibNamespaceUri + m_dimsAttrName, StringUtils.GetArrayDimsString(arrayDims), m_documentDefaultNamespace);
RegisterYaxLibNamespace();
}
return elemToAdd;
}