void UniversalWriterSubnodes(SerializationWriterContext ctx, object instance, IEnumerable <Element> elements)
 {
     // PROPERTY as SUBNODE:
     // composite not null
     // collection
     foreach (var element in elements.OrderBy(x => x.Name))
     {
         var subObj = element.GetValue(instance);
         if (!IsInAttrib(subObj))
         {
             var subList = subObj as IList;
             if (subObj != null && (subList == null || subList.Count > 0))                     // subList == null - this is composite
             {
                 ctx.Write($"{Indentation(ctx.Indentation)}<{instance.GetType().Name}.{element.Name}>");
                 ctx.Indentation++;
                 if (subList != null)
                 {
                     ctx.Result.AppendLine();
                     for (int index = 0; index < subList.Count; index++)
                     {
                         var item = subList[index];
                         GetWriter(item.GetType())(ctx, item);
                     }
                 }
                 else
                 {
                     UniversalWriter(ctx, subObj);
                 }
                 ctx.Indentation--;
                 ctx.WriteLine($"{Indentation(ctx.Indentation)}</{instance.GetType().Name}.{element.Name}>");
             }
         }
     }
 }
 void UniversalWriterAttributes(SerializationWriterContext ctx, object instance, IEnumerable <Element> elements)
 {
     // PROPERTY as ATTRIBUTE:
     // primitive
     // composite null
     foreach (var element in elements.OrderBy(x => x.Name))
     {
         var val = element.GetValue(instance);
         if (IsInAttrib(val))
         {
             if (element.DefaultValueAttribute == null || !Equals(element.DefaultValueAttribute.Value, val))
             {
                 if (ReferenceEquals(null, val))
                 {
                     var x = ctx.GetAliasFor("http://schemas.microsoft.com/winfx/2006/xaml");
                     val = $"{{{x}:Null}}";
                 }
                 val = ConvertToString(val);
                 ctx.Write($@" {element.Name}=""{val}""");
             }
         }
     }
 }
        private void PrecompiledWriter(SerializationWriterContext ctx, object obj)
        {
            var sample = (Sample)obj;

            ctx.Write($@"<Sample Prop1=""{sample.Prop1}"" Prop2=""{sample.Prop2}"" xmlns=""test"" />");
        }
        void UniversalWriter(SerializationWriterContext ctx, object instance)
        {
            var type     = instance.GetType();
            var meta     = GetTypeMetada(type);
            var elements = meta.Elements;

            ctx.NamespacesUsed.Add(meta.XmlNamespace);
            string alias;

            if (ctx.Indentation > 0 && meta.XmlNamespace != ctx.RootNamespace || meta.IsX())
            {
                alias = ctx.GetAliasFor(meta.XmlNamespace) + ':';
            }
            else
            {
                alias             = null;
                ctx.RootNamespace = meta.XmlNamespace;
            }

            if (ctx.Indentation != 0 && ctx.Result[ctx.Result.Length - 1] != '\n')
            {
                ctx.Result.AppendLine();
            }
            ctx.Write($"{Indentation(ctx.Indentation)}<{alias}{type.Name}");

            UniversalWriterAttributes(ctx, instance, elements);

            // <nested in new builder>
            var subCtx = ctx.Nested();

            UniversalWriterSubnodes(subCtx, instance, elements);
            // </nested in new builder>

            if (!ctx.XmlnsEmited && ctx.Indentation == 0)
            {
                if (!string.IsNullOrEmpty(ctx.RootNamespace))
                {
                    ctx.Write($" xmlns=\"{ctx.RootNamespace}\"");
                }
                foreach (var ns in ctx.NamespacesUsed)
                {
                    if (ns != ctx.RootNamespace)
                    {
                        ctx.Write($" xmlns:{ctx.GetAliasFor(ns)}=\"{ns}\"");
                    }
                }
                ctx.XmlnsEmited = true;
            }

            // <body>
            string body = null;

            if (meta.IsBody())
            {
                body = string.Format(CultureInfo.InvariantCulture, "{0}", instance);
            }
            // </body>


            if (subCtx.Result.Length > 0)
            {
                ctx.WriteLine(">");
                ctx.Write(subCtx.Result.ToString());
                ctx.Write($"{Indentation(ctx.Indentation)}</{alias}{type.Name}>");
            }
            else if (body != null)
            {
                ctx.Write(">");
                ctx.Write(body);
                ctx.Write($"</{alias}{type.Name}>");
            }
            else
            {
                ctx.Write(" />");
            }
            if (ctx.Indentation != 0)
            {
                ctx.Result.AppendLine();
            }
        }