XML Processing Utilities in C#

1 Basic XML Serialization and Deserialization

For standard object-to-XML conversiosn, you can use direct serialization methods.

public class XmlProcessor
{
    /// <summary>
    /// Converts XML string to object
    /// </summary>
    public static T ParseXml<T>(string xmlContent) where T : class
    {
        try
        {
            using (var reader = new StringReader(xmlContent))
            {
                var serializer = new XmlSerializer(typeof(T));
                return serializer.Deserialize(reader) as T;
            }
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// Serializes object to XML string
    /// </summary>
    public static string ToXmlString<T>(T entity)
    {
        using (var writer = new StringWriter())
        {
            var serializer = new XmlSerializer(entity.GetType());
            serializer.Serialize(writer, entity);
            return writer.ToString();
        }
    }

    /// <summary>
    /// Serializes object to XML file
    /// </summary>
    public static void SaveToXml<T>(T entity, string filePath)
    {
        var namespaces = new XmlSerializerNamespaces();
        namespaces.Add(string.Empty, string.Empty);
        
        using (var writer = new StreamWriter(filePath))
        {
            var serializer = new XmlSerializer(entity.GetType());
            serializer.Serialize(writer, entity, namespaces);
        }
    }

    /// <summary>
    /// Serializes to XML without namespace declarations
    /// </summary>
    public static string ToXmlStringWithoutNamespace<T>(T entity)
    {
        using (var writer = new StringWriter())
        {
            var namespaces = new XmlSerializerNamespaces();
            namespaces.Add(string.Empty, string.Empty);
            var serializer = new XmlSerializer(entity.GetType());
            serializer.Serialize(writer, entity, namespaces);
            return writer.ToString();
        }
    }

    /// <summary>
    /// Serializes to XML without declaration and namespace
    /// </summary>
    public static string ToCleanXml<T>(T entity)
    {
        var encoding = Encoding.UTF8;
        var settings = new XmlWriterSettings
        {
            Encoding = encoding,
            OmitXmlDeclaration = true
        };
        
        var namespaces = new XmlSerializerNamespaces();
        namespaces.Add(string.Empty, string.Empty);
        
        using (var stream = new MemoryStream())
        using (var writer = XmlWriter.Create(stream, settings))
        {
            var serializer = new XmlSerializer(entity.GetType());
            serializer.Serialize(writer, entity, namespaces);
            
            ApplyXmlFormatting(stream);
            return encoding.GetString(stream.ToArray());
        }
    }

    /// <summary>
    /// Applies proper indentation to XML
    /// </summary>
    private static void ApplyXmlFormatting(MemoryStream stream)
    {
        stream.Position = 0;
        var reader = new StreamReader(stream);
        var xmlContent = reader.ReadToEnd();

        var document = XDocument.Parse(xmlContent);
        
        stream.SetLength(0);
        
        var formattedSettings = new XmlWriterSettings
        {
            OmitXmlDeclaration = true,
            Indent = true,
            IndentChars = "    ",
            NewLineChars = "\r\n",
            NewLineHandling = NewLineHandling.Replace
        };

        using (var formattedStream = new MemoryStream())
        using (var writer = XmlWriter.Create(formattedStream, formattedSettings))
        {
            document.WriteTo(writer);
            writer.Flush();
            
            formattedStream.Position = 0;
            formattedStream.CopyTo(stream);
        }
    }
}

2 Handling Special XML Structures

For custom XML structures, use attributes to control the generated XML.

[XmlRoot("Request")]
public class ApiRequest
{
    public RequestHeader Header { get; set; } = new();

    [XmlElement("Payload")]
    public RequestPayload Payload { get; set; }
}

public class RequestPayload 
{
    [XmlArray("Employees"), XmlArrayItem("Employee")]
    public List<Employee> Employees { get; set; } = new();
}

Resulitng XML structure:

<Request>
    <Header></Header>
    <Payload>
        <Employees>
            <Employee></Employee>
            <Employee></Employee>
        </Employees>
    </Payload>
</Request>

3 Working with Existing XML Data

3.1 Parse XML to object using deserializasion (see utility class above)

3.2 Direct XML manipulation using LINQ to XML

string xmlData = @"<Request>
    <Header>API Header</Header>
    <Payload>
        <Employees>
            <Employee>John Doe</Employee>
            <Employee>Jane Smith</Employee>
            <Employee></Employee>
        </Employees>
    </Payload>
</Request>";

var document = XDocument.Parse(xmlData);

// Extract element values
var headerValue = document.Descendants("Header").FirstOrDefault()?.Value;
var firstEmployee = document.Descendants("Employee").FirstOrDefault()?.Value;

// Get entire element as XElement
var payloadElement = document.Descendants("Payload").FirstOrDefault();

Console.WriteLine(headerValue);
Console.WriteLine(firstEmployee);
Console.WriteLine(payloadElement);

Console output:

API Header
John Doe
<Payload>
  <Employees>
    <Employee>John Doe</Employee>
    <Employee>Jane Smith</Employee>
    <Employee></Employee>
  </Employees>
</Payload>

Tags: C# XML serialization LINQ to XML

Posted on Sat, 03 Oct 2026 16:30:38 +0000 by kevinkhan