mirror of
https://github.com/Stone-Red-Code/CuteUtils.git
synced 2026-09-04 08:56:13 +02:00
Add XML helper
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
using CuteUtils.Misc;
|
||||||
|
|
||||||
|
namespace CuteUtils.Tests.Misc;
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class XmlHelperTests
|
||||||
|
{
|
||||||
|
public class TestModel
|
||||||
|
{
|
||||||
|
public string? Name { get; set; }
|
||||||
|
public int Age { get; set; }
|
||||||
|
public NestedModel? Child { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NestedModel
|
||||||
|
{
|
||||||
|
public string? Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SerializeDeserialize_RoundTrip_RetainsData()
|
||||||
|
{
|
||||||
|
TestModel model = new TestModel
|
||||||
|
{
|
||||||
|
Name = "Alice",
|
||||||
|
Age = 30,
|
||||||
|
Child = new NestedModel { Value = "Inner" }
|
||||||
|
};
|
||||||
|
|
||||||
|
string xml = XmlHelper.Serialize(model);
|
||||||
|
Assert.IsFalse(string.IsNullOrWhiteSpace(xml), "Serialized XML should not be empty.");
|
||||||
|
Assert.Contains("Alice", xml, "XML should contain the Name value.");
|
||||||
|
Assert.Contains("30", xml, "XML should contain the Age value.");
|
||||||
|
Assert.Contains("Inner", xml, "XML should contain the Nested Value.");
|
||||||
|
|
||||||
|
TestModel? deserialized = XmlHelper.Deserialize<TestModel>(xml);
|
||||||
|
Assert.IsNotNull(deserialized, "Deserialized object should not be null.");
|
||||||
|
Assert.AreEqual(model.Name, deserialized!.Name);
|
||||||
|
Assert.AreEqual(model.Age, deserialized.Age);
|
||||||
|
Assert.AreEqual(model.Child?.Value, deserialized.Child?.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Serialize_OmitsNamespaceDeclarations()
|
||||||
|
{
|
||||||
|
TestModel model = new TestModel { Name = "Bob", Age = 25 };
|
||||||
|
string xml = XmlHelper.Serialize(model);
|
||||||
|
|
||||||
|
// Expect no namespace attributes like xmlns or common schema prefixes
|
||||||
|
Assert.DoesNotContain("xmlns", xml, "XML should not contain namespace declarations.");
|
||||||
|
Assert.DoesNotContain("xsi:", xml, "XML should not contain xsi prefix.");
|
||||||
|
Assert.DoesNotContain("xsd:", xml, "XML should not contain xsd prefix.");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Deserialize_NullXml_ThrowsArgumentNullException()
|
||||||
|
{
|
||||||
|
_ = Assert.ThrowsExactly<ArgumentNullException>(() => XmlHelper.Deserialize<TestModel>(null!));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetXmlSchema_ReturnsSchemaContainingTypeName()
|
||||||
|
{
|
||||||
|
string schema = XmlHelper.GetXmlSchema<TestModel>();
|
||||||
|
Assert.IsFalse(string.IsNullOrWhiteSpace(schema), "Schema should not be empty.");
|
||||||
|
Assert.IsGreaterThanOrEqualTo(0, schema.IndexOf("schema", StringComparison.OrdinalIgnoreCase), "Schema should contain 'schema' element.");
|
||||||
|
Assert.Contains("TestModel", schema, "Schema should reference the TestModel type.");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Schema;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace CuteUtils.Misc;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides simple XML serialization and deserialization helpers and schema generation helpers.
|
||||||
|
/// </summary>
|
||||||
|
public static class XmlHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Deserializes an XML string into an instance of <typeparamref name="T"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The target reference type to deserialize into. Must be a class.</typeparam>
|
||||||
|
/// <param name="xml">The XML string to deserialize. Must not be null.</param>
|
||||||
|
/// <param name="settings">Optional <see cref="XmlReaderSettings"/> to control reader behavior. If null, default settings are used.</param>
|
||||||
|
/// <returns>An instance of <typeparamref name="T"/> if deserialization succeeds; otherwise, <c>null</c>.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">Thrown when <paramref name="xml"/> is null.</exception>
|
||||||
|
/// <exception cref="InvalidOperationException">May be thrown by <see cref="XmlSerializer"/> when deserialization fails.</exception>
|
||||||
|
public static T? Deserialize<T>(string xml, XmlReaderSettings? settings = null) where T : class
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(xml);
|
||||||
|
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(T));
|
||||||
|
|
||||||
|
using StringReader stringReader = new StringReader(xml);
|
||||||
|
using XmlReader xmlReader = XmlReader.Create(stringReader, settings);
|
||||||
|
|
||||||
|
return serializer.Deserialize(xmlReader) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serializes an object to its XML representation.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the object to serialize.</typeparam>
|
||||||
|
/// <param name="obj">The object instance to serialize. Must not be null.</param>
|
||||||
|
/// <param name="settings">Optional <see cref="XmlWriterSettings"/> to control writer behavior. If null, default settings are used.</param>
|
||||||
|
/// <param name="xmlSerializerNamespaces">Optional <see cref="XmlSerializerNamespaces"/> to control namespace declarations. If null, an empty namespace is used to omit declarations.</param>
|
||||||
|
/// <returns>A string containing the XML representation of <paramref name="obj"/>.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">Thrown when <paramref name="obj"/> is null.</exception>
|
||||||
|
/// <exception cref="InvalidOperationException">May be thrown by <see cref="XmlSerializer"/> when serialization fails.</exception>
|
||||||
|
public static string Serialize<T>(T obj, XmlWriterSettings? settings = null, XmlSerializerNamespaces? xmlSerializerNamespaces = null)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(obj);
|
||||||
|
|
||||||
|
settings ??= new XmlWriterSettings();
|
||||||
|
|
||||||
|
if (xmlSerializerNamespaces == null)
|
||||||
|
{
|
||||||
|
xmlSerializerNamespaces = new XmlSerializerNamespaces();
|
||||||
|
xmlSerializerNamespaces.Add(string.Empty, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlSerializer xmlSerializer = new(typeof(T));
|
||||||
|
|
||||||
|
// Omit namespace declarations by adding an empty namespace
|
||||||
|
xmlSerializerNamespaces.Add(string.Empty, string.Empty);
|
||||||
|
|
||||||
|
using StringWriter stringWriter = new StringWriter();
|
||||||
|
using XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings);
|
||||||
|
|
||||||
|
xmlSerializer.Serialize(xmlWriter, obj, xmlSerializerNamespaces);
|
||||||
|
return stringWriter.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates XML schema definitions for the specified type <typeparamref name="T"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type for which to generate XML schema.</typeparam>
|
||||||
|
/// <param name="settings">Optional <see cref="XmlWriterSettings"/> to control output formatting. If null, default settings are used.</param>
|
||||||
|
/// <returns>A string containing one or more XML schema documents representing <typeparamref name="T"/>.</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">May be thrown when schema export fails.</exception>
|
||||||
|
public static string GetXmlSchema<T>(XmlWriterSettings? settings = null)
|
||||||
|
{
|
||||||
|
settings ??= new XmlWriterSettings();
|
||||||
|
|
||||||
|
XmlSchemas schemas = [];
|
||||||
|
XmlSchemaExporter exporter = new XmlSchemaExporter(schemas);
|
||||||
|
XmlTypeMapping mapping = new XmlReflectionImporter().ImportTypeMapping(typeof(T));
|
||||||
|
|
||||||
|
exporter.ExportTypeMapping(mapping);
|
||||||
|
|
||||||
|
using StringWriter stringWriter = new StringWriter();
|
||||||
|
using XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings);
|
||||||
|
|
||||||
|
foreach (XmlSchema schema in schemas)
|
||||||
|
{
|
||||||
|
schema.Write(xmlWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringWriter.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user