Xml in C#

Here’s the translation of the XML handling example from Go to C#:

using System;
using System.Xml.Serialization;
using System.Text;
using System.IO;

// Plant will be mapped to XML. Field attributes contain directives for the
// serializer and deserializer. Here we use some special features
// of the XML serialization: the XmlRoot attribute dictates
// the name of the XML element representing this class;
// XmlAttribute means that the Id field is an XML
// attribute rather than a nested element.
[XmlRoot("plant")]
public class Plant
{
    [XmlAttribute("id")]
    public int Id { get; set; }

    [XmlElement("name")]
    public string Name { get; set; }

    [XmlArray("origin")]
    [XmlArrayItem("country")]
    public string[] Origin { get; set; }

    public override string ToString()
    {
        return $"Plant id={Id}, name={Name}, origin=[{string.Join(", ", Origin)}]";
    }
}

public class Program
{
    public static void Main()
    {
        var coffee = new Plant
        {
            Id = 27,
            Name = "Coffee",
            Origin = new string[] { "Ethiopia", "Brazil" }
        };

        // Serialize XML representing our plant; using
        // XmlSerializer to produce a more
        // human-readable output.
        var serializer = new XmlSerializer(typeof(Plant));
        var sb = new StringBuilder();
        using (var writer = new StringWriter(sb))
        {
            serializer.Serialize(writer, coffee);
        }
        var xml = sb.ToString();
        Console.WriteLine(xml);

        // To add a generic XML declaration to the output, we can use
        // XmlWriterSettings.
        var settings = new System.Xml.XmlWriterSettings
        {
            Indent = true,
            OmitXmlDeclaration = false
        };
        sb.Clear();
        using (var writer = System.Xml.XmlWriter.Create(new StringWriter(sb), settings))
        {
            serializer.Serialize(writer, coffee);
        }
        Console.WriteLine(sb.ToString());

        // Use Deserialize to parse a stream of bytes with XML
        // into a data structure. If the XML is malformed or
        // cannot be mapped onto Plant, an exception
        // will be thrown.
        using (var reader = new StringReader(xml))
        {
            var p = (Plant)serializer.Deserialize(reader);
            Console.WriteLine(p);
        }

        var tomato = new Plant
        {
            Id = 81,
            Name = "Tomato",
            Origin = new string[] { "Mexico", "California" }
        };

        // The XmlArray and XmlArrayItem attributes tell the serializer
        // to nest all Plants under <parent><child>...</child></parent>
        [XmlRoot("nesting")]
        public class Nesting
        {
            [XmlArray("parent")]
            [XmlArrayItem("child", typeof(Plant))]
            public Plant[] Plants { get; set; }
        }

        var nesting = new Nesting
        {
            Plants = new Plant[] { coffee, tomato }
        };

        sb.Clear();
        var nestingSerializer = new XmlSerializer(typeof(Nesting));
        using (var writer = new StringWriter(sb))
        {
            nestingSerializer.Serialize(writer, nesting);
        }
        Console.WriteLine(sb.ToString());
    }
}

This C# code demonstrates XML serialization and deserialization using the System.Xml.Serialization namespace. Here’s a breakdown of the key points:

  1. We define a Plant class with XML attributes to control serialization.

  2. The XmlSerializer class is used to serialize and deserialize objects.

  3. We use StringWriter and StringBuilder to capture the XML output as a string.

  4. To add an XML declaration, we use XmlWriterSettings and XmlWriter.

  5. Deserialization is performed using the Deserialize method of XmlSerializer.

  6. We demonstrate nested XML structures using a Nesting class with appropriate XML attributes.

To run this program, save it as a .cs file and compile it using the C# compiler. Then run the resulting executable. The output will show various XML representations of the data structures and the results of serialization and deserialization.

This example showcases C#’s built-in XML handling capabilities, which are quite robust and flexible, allowing for easy mapping between C# objects and XML structures.