0
\$\begingroup\$

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

\$\endgroup\$

closed as off-topic by t3chb0t, Ludisposed, Graipher, Stephen Rauch, Mast Sep 26 '18 at 14:38

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – t3chb0t, Ludisposed, Graipher, Stephen Rauch, Mast
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 4
    \$\begingroup\$ I think you shouldn't have removed any code but you definitely should have included the schema of the xml and the models you are converting to it. \$\endgroup\$ – t3chb0t Sep 26 '18 at 10:40
  • 3
    \$\begingroup\$ When you say "schema" do you mean that you have an XSD document, a DTD, some other designed-for-automation document, or a textual description? \$\endgroup\$ – Peter Taylor Sep 26 '18 at 11:26
  • \$\begingroup\$ I do have an XSD. \$\endgroup\$ – SilentRage47 Sep 26 '18 at 13:34
1
\$\begingroup\$

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());
    }
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.