Khurram Majeed
Khurram Majeed

Reputation: 2391

Generic way of creating XML files in C#

I am trying to create a class which saves/reads multiple XML files using LINQ and Genertics.

I am looking for generic way of saving XMl files of multiple type (i.e data in them)

Every XML file will have following format

<ROOT>
     <!-- First Element/First Row -->
     <NODE>
           <COL1>Some value</COL1>
           .....  
           <COLn>Some value</COLn>
     </NODE>
     .........
     <!-- Nth Element = nth row -->
     <NODE>
           <COL1>Some value</COL1>
           .....  
           <COLn>Some value</COLn>
     </NODE>
</ROOT>

Every file will have a different ROOT, NODE and COLx. The Number of columns and data in them depends on the Multi-Dim array input. This input array also gives the number of NODES tags in xml (elements in array).

A method to save an XML file looks like

public void SaveFirstXmlFile()
{
    XElement xdoc = new XElement("ThisDocsRoot");
    //Iterate for number of rows(elements of data)            
    for (int nodes= 1; nodes<= NUMBER_OF_NODES; nodes++)
    {
        xdoc.Add(new XElement(row,
                              new XElement("Col 1", "Some Value"),
                              new XElement("Col 2", "Some Value"),
                              new XElement("Col 3", "Some Value")
                     ));
    } 
    xdoc.Save("/Path/To/XML/File");
}

I wanted to tweak this method so that it works for multiple XML files.I don't know if it is correct way of doiung it, but I strated creating CLasses which define the root,node,columns and path for the XML file. and The data comes from Multi-Dim Arrays created by some other classes.

private class AClassforSomeXMLFile
{
    private readonly String _root;
    private readonly String _row;
    private readonly String[] _columns;
    private readonly String _exportPath;

    public UsageData()
    {

        _exportPath = string.Format(@"{0}\xyz.xml",Path.GetDirectoryName(Application.ExecutablePath));

        _root = "ROOT";
        _row = "NODE";
        _columns = new string[]
            {
                "COL1","COL2", "COL3","COL4",
            };
    }

    public string ROOT {  get { return _root; } }

    public string ROW { get { return _row; } }

    public string[] COLS  { get { return _columns; }}

    public string EPATH { get { return _exportPath; }}
}

Upvotes: 0

Views: 1942

Answers (2)

Alexander
Alexander

Reputation: 4173

You can add constructor to AClassforSomeXMLFile class, to populate root, row and columns values, and then pass instance of definition to your SaveFirstXmlFile function:

private class XmlDefinition
{
    public string ROOT { get;set; }
    public string ROW { get;set; }
    public string[] COLS  { get;set; }
    public string EPATH { get;set; }
}


void Foo()
{
  var employeeDefinition = new XmlDefinition 
  { 
    ROOT = "Employees", 
    ROW = "Employee", 
    COLS = new[] { "Name", "Address", "Department", "Salary" },
    EPATH = string.Format(@"{0}\employee.xml",Path.GetDirectoryName(Application.ExecutablePath))
  };

  SaveFirstXmlFile(employeeDefinition); //save employees

  var productDefinition = new XmlDefinition 
  { 
    ROOT = "Products", 
    ROW = "Product", 
    COLS = new[] { "Name", "Description", "Cost" },
    EPATH = string.Format(@"{0}\products.xml",Path.GetDirectoryName(Application.ExecutablePath))
  };

  SaveFirstXmlFile(productDefinition); //save products
}

public void SaveFirstXmlFile(AClassforSomeXMLFile definition)
{
    XElement xdoc = new XElement(definition.ROOT);
    //Iterate for number of rows(elements of data)            
    for (int nodes = 1; nodes <= NUMBER_OF_NODES; nodes++)
    {
        var cols = from c in definition.COLS select new XElement(c, "Some Value");
        xdoc.Add(new XElement(definition.ROW, cols.ToArray()));
    } 
    xdoc.Save(definition.EPATH);
}

Upvotes: 1

I do not fully understand the ask here, but It looks like it might be satisfied if you format your XML like this

 <NODE>
       <COL>Some value</COL>
       .....  
       <COL>Some value</COL>
 </NODE>

and then you can read all your COLs into a list

XElement xdoc = new XElement("ThisDocsRoot");
List<XElement> Cols = xdoc.Elements("COL").ToList();

Upvotes: 1

Related Questions