CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Threading;
using System.ComponentModel;
using System.Xml.Linq;
using System.Reflection;
using System.Data;
using System.Xml.Schema;
using System.Text.RegularExpressions;
using System.Net;
using System.Xml.XPath;
using System.Globalization;
using System.Collections;
// https://stackoverflow.com/questions/42716646/order-xml-elements-for-serialization
public class Service
{
[XmlAttribute("__serviceType")]
public string ServiceType { get; set; }
[XmlIgnore]
public Perform Perform { get; set; }
[XmlIgnore]
public List<InputData> InputData { get; set; }
[XmlElement("__perform", Type = typeof(Perform))]
[XmlElement("__inputData", Type = typeof(InputData))]
public object[] XmlInputAndPerformance
{
get
{
var inputData = (InputData ?? Enumerable.Empty<InputData>()).Cast<object>();
var performData = Perform == null ? Enumerable.Empty<object>() : new object[] { Perform };
return inputData.Take(1)
.Concat(performData)
.Concat(inputData.Skip(1))
.ToArray();
}
set
{
if (value == null)
return;
var newInputs = value.OfType<InputData>().ToList();
var newPerform = value.OfType<Perform>().ToList();
if (newInputs.Count + newPerform.Count != value.Length)
throw new ArgumentException("Unknown type.");
if (newPerform.Count > 1)
throw new ArgumentException("Too many Perform objects.");
if (newPerform.Count > 0)
Perform = newPerform[0];
(InputData = InputData ?? new List<InputData>()).AddRange(newInputs);
}
}
[XmlElement("__execute")]
public Execute Execute { get; set; }
[XmlElement("__requestData")]
public RequestData RequestData { get; set; }
public Service() { }
}
[XmlRoot(ElementName = "__execute")]
public class Execute
{
}
[XmlRoot(ElementName = "BaseToChange")]
public class BaseToChange
{
[XmlElement(ElementName = "__name")]
public string __name { get; set; }
}
[XmlRoot(ElementName = "__inputData")]
public class InputData
{
[XmlElement(ElementName = "BaseToChange")]
public BaseToChange BaseToChange { get; set; }
[XmlElement(ElementName = "ObjectChanges")]
public ObjectChanges ObjectChanges { get; set; }
}
[XmlRoot(ElementName = "__perform")]
public class Perform
{
[XmlElement(ElementName = "__eventName")]
public string __eventName { get; set; }
}
[XmlRoot(ElementName = "ObjectChanges")]
public class ObjectChanges
{
[XmlElement(ElementName = "Name")]
public string Name { get; set; }
}
[XmlRoot(ElementName = "__requestData")]
public class RequestData
{
[XmlElement(ElementName = "CompletionMsg")]
public string CompletionMsg { get; set; }
}
[XmlRoot(ElementName = "__Root")]
public class __Root
{
[XmlElement(ElementName = "__service")]
public Service __service { get; set; }
[XmlAttribute(AttributeName = "__version")]
public string __version { get; set; }
[XmlAttribute(AttributeName = "__encryption")]
public string __encryption { get; set; }
}
static class TestClass
{
static string GetXml()
{
var xml = @"<?xml version=""1.0""?>
<__Root __version=""1.1"" __encryption=""2"">
<__service __serviceType=""Test"">
<__inputData>
<BaseToChange>
<__name>TestName</__name>
</BaseToChange>
</__inputData>
<__perform>
<__eventName>Event</__eventName>
</__perform>
<__inputData>
<ObjectChanges>
<Name>Test</Name>
</ObjectChanges>
</__inputData>
<__execute />
<__requestData>
<CompletionMsg />
</__requestData>
</__service>
</__Root>";
return xml;
}
public static void Test()
{
Test0();
Console.WriteLine("");
Test1();
}
public static void Test0()
{
var xml = GetXml();
Console.WriteLine("Testing input XML: ");
Console.WriteLine(xml);
var root = xml.LoadFromXml<__Root>();
var xml2 = root.GetXml(true);
Console.WriteLine("\nDeserialized and re-serialized XML: ");
Console.WriteLine(xml2);
var ok = XNode.DeepEquals(XElement.Parse(xml), XElement.Parse(xml2));
if (!ok)
throw new AssertionFailedException("Original and re-serialized XML are NOT equivalent.");
else
Console.WriteLine("Original and re-serialized XML are equivalent.");
}
private static void Test1()
{
Console.WriteLine("Testing empty {0}", typeof(__Root));
var root3 = new __Root() { __service = new Service() };
var xml3 = root3.GetXml();
Console.WriteLine(xml3);
var root4 = xml3.LoadFromXml<__Root>();
var xml4 = root4.GetXml();
Console.WriteLine(xml4);
}
}
public class Program
{
public static void Main()
{
TestClass.Test();
}
}
public static class XmlSerializationHelper
{
public static T LoadFromXml<T>(this string xmlString, XmlSerializer serial = null)
{
serial = serial ?? new XmlSerializer(typeof(T));
T returnValue = default(T);
using (StringReader reader = new StringReader(xmlString))
{
object result = serial.Deserialize(reader);
if (result is T)
{
returnValue = (T)result;
}
}
return returnValue;
}
public static string GetXml<T>(this T obj, bool omitStandardNamespaces)
{
return obj.GetXml(null, omitStandardNamespaces);
}
public static string GetXml<T>(this T obj, XmlSerializer serializer = null, bool omitStandardNamespaces = false)
{
XmlSerializerNamespaces ns = null;
if (omitStandardNamespaces)
{
ns = new XmlSerializerNamespaces();
ns.Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
}
using (var textWriter = new StringWriter())
{
var settings = new XmlWriterSettings() { Indent = true }; // For cosmetic purposes.
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
(serializer ?? new XmlSerializer(obj.GetType())).Serialize(xmlWriter, obj, ns);
return textWriter.ToString();
}
}
}
public class AssertionFailedException : System.Exception
{
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
}
public static class Assert
{
public static void IsTrue(bool value)
{
if (value == false)
throw new AssertionFailedException("failed");
}
}