Writing XML in C# from defined schema I'm creating an XML from a defined schema I need to follow.

This is my code:

using (XmlWriter writer = XmlWriter.Create(desktopPath + "\fatt.xml", settings))
{
  writer.WriteStartDocument();

  #region FatturaElettronicaHeader 1

  writer.WriteStartElement("FatturaElettronicaHeader");

  #region DatiTrasmissione 1.1
  writer.WriteStartElement("DatiTrasmissione"); 

  var statoAnag = statiRep.GetId(anagraficoCliente.stato); 

  writer.WriteStartElement("IdTrasmittente"); 
  writer.WriteElementString("IdPaese",statoAnag.codice_iso); 
  writer.WriteElementString("IdCodice",anagraficoCliente.codice_fiscale); 
  writer.WriteEndElement();

  writer.WriteElementString("ProgressivoInvio", "0");
  writer.WriteElementString("FormatoTrasmissione",FORMATO_TRASMISSIONE); 

  writer.WriteElementString("CodiceDestinatario",codiceSdi); 

  writer.WriteElementString("PECDestinatario","prova@pec.it"); 
  writer.WriteEndElement();

  #endregion DatiTrasmissione 1.1

  #region 2
  ....
  #endregion 2

  writer.WriteEndDocument();
}


Basically I just have to read data from my db and then put in a xml file.

It works fine but I think is not really readable even if I used a lot of region to tidy up code.

What can I do to improve my code ? If there's any
When I had to create an XML file for one of my projects, I basically created a class for each element and passed along a class that contained all the data I needed to use in the XML.

It started with this class:

internal sealed class XmlCreator
{
    public static XElement Execute(RequestConfig requestConfig)
    {
        return ImportElementCreator.Execute(requestConfig);
    }
}


Which in turn used this class:

internal sealed class ImportElementCreator
{
    public static XElement Execute(RequestConfig requestConfig)
    {
        var element = new XElement("Import");

        element.Add(PersElementCreator.Execute(requestConfig));

        return element;
    }
}


etc etc etc. I'm sure you get the point.

Part of the reason was that the resulting XML file could differ, depending on the action in the request: an "Update" required more data than a "Delete", and thus some classes contained some logic:

    public static XElement Execute(RequestConfig requestConfig)
    {
        var element = new XElement("Access-Rule",
            new XAttribute("id", requestConfig.Position ?? 1), 
            new XAttribute("operation", requestConfig.RequestType.ToString().ToLowerInvariant())
            );

        if (requestConfig.RequestType != RequestType.Update)
        {
            return element;
        }

        element.Add(RuleElementCreator.Execute(requestConfig.AccessRuleId));

        element.Add(StartDateElementCreator.Execute(requestConfig.StartDate));

        element.Add(EndDateElementCreator.Execute(requestConfig.EndDate));

        return element;
    }


The downside is that you might end up with a lot of small classes if you have a complicated XML file, and that you need to look out for duplicate class names.



Of course, if you look at XmlCreator, you end up with an XElement, not an XML file.

To actually write the XML file, I had this:

internal sealed class FileWriter
{
    private readonly string _localDirectory;
    private readonly XmlWriterSettings _xmlWriterSettings;

    public FileWriter(string localDirectory)
    {
        _localDirectory = localDirectory;

        _xmlWriterSettings = new XmlWriterSettings
        {
            Indent = true,
            OmitXmlDeclaration = false,
            Encoding = _idTechConfiguration.Encoding
        };
    }

    public string Execute(RequestConfig requestConfig, XElement content)
    {
        var xmlDirectory = Path.Combine(_localDirectory, "xml");
        Directory.CreateDirectory(xmlDirectory);

        var filePath = Path.Combine(xmlDirectory, GetFileName(requestConfig));
        using (var xmlWriter = XmlWriter.Create(filePath, _xmlWriterSettings))
        {
            content.WriteTo(xmlWriter);
        }

        return filePath;
    }

    private string GetFileName(RequestConfig requestConfig)
    {
        return string.Format("{0}_{1}_{2}_{3}_{4}.xml",
            requestConfig.ApplicationName,
            requestConfig.RequestType,
            requestConfig.UserData, 
            DateTime.Now.AsYyyyMmDdDashed(), 
            DateTime.Now.AsHhMmSsDashed());
    }
}