CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
// https://stackoverflow.com/questions/44652753/xmlserialization-with-xmlanyelement-to-xmlnode-and-order-property
[XmlRoot]
[Serializable]
public class A
{
[XmlElement("asd", Order = 1)]
public string asd { get; set; }
[XmlIgnore]
public string[] qwe { get; set; }
[XmlElement("nnn", Order = 2)]
public XmlNodeWrapper [] nnn
{
get
{
if (qwe == null)
return null;
var xml = new XmlDocument();
var nodes = new List<XmlNode>(qwe.Length);
foreach (var q in qwe)
{
var nnnTag = xml.CreateNode(XmlNodeType.Element, "nnn", null);
nnnTag.InnerText = q;
nodes.Add(nnnTag);
}
return nodes.Select(n => (XmlNodeWrapper)n.ChildNodes).ToArray();
}
set
{
if (value == null)
return;
qwe = value.Select(tag => tag.InnerText()).ToArray();
}
}
[XmlElement("aaa", Order = 3)]
public string aaa { get; set; }
}
[XmlType(AnonymousType = true)]
public struct XmlNodeWrapper
{
public static implicit operator XmlNodeWrapper(XmlNodeList nodes)
{
return new XmlNodeWrapper { Nodes = nodes == null ? null : nodes.Cast<XmlNode>().ToArray() };
}
public static implicit operator XmlNode[](XmlNodeWrapper wrapper)
{
return wrapper.Nodes;
}
// Marking the Nodes property with both [XmlAnyElement] and [XmlText] indicates that the node array
// may contain mixed content (I.e. both XmlElement and XmlText objects).
// Hat tip: https://stackoverflow.com/questions/25995609/xmlserializer-node-containing-text-xml-text
[XmlAnyElement]
[XmlText]
public XmlNode[] Nodes { get; set; }
public string InnerText()
{
if (Nodes == null)
return null;
return String.Concat(Nodes.Select(n => n.InnerText));
}
}
class TestClass
{
public static void Test()
{
var a = new A
{
aaa = "aaa",
asd = "asd",
qwe = new[] { "q", "w", "e" }
};
var s = Serialize(a);
Console.WriteLine(s);
var ss = Deserialize<A>(s);
var s2 = Serialize(ss);
Console.WriteLine(s2);
Console.WriteLine(string.Format("Equals: {0};", s == s2));
Assert.IsTrue(s == s2);
Console.WriteLine();
}
public static string Serialize<T>(T a)
{
var s = new XmlSerializer(typeof(T));
using (var ms = new MemoryStream())
{
using (TextWriter sw = new StreamWriter(ms))
{
s.Serialize(sw, a);
ms.Seek(0, 0);
using (var sr = new StreamReader(ms))
{
return sr.ReadToEnd();
}
}
}
}
public static T Deserialize<T>(string a)
{
var s = new XmlSerializer(typeof(T));
var bytes = Encoding.ASCII.GetBytes(a);
using (var ms = new MemoryStream(bytes))
{
return (T)s.Deserialize(ms);
}
}
}
public class AssertionFailedException : System.Exception
{
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
}
public static class Assert
{
public static void IsTrue(bool value)
{
IsTrue(value, "Assertion failed");
}
public static void IsTrue(bool value, string message)
{
if (value == false)
throw new AssertionFailedException(message);
}
}
public class Program
{
public static void Main()
{
TestClass.Test();
}
}