Search code examples
c#xmllinqxelement

Convert many text files in xml files, keeping the same file name C#


UPDATED - I'm trying to convert a lot of text files (up to 3K files) to XML files, using C#. There are two steps that I would like to follow: 1) Get some data using specific delimiter ":". 2) Use the same name of *.txt file to create *.xml file in another folder.

I've spent a lot of time to get the data information from text files using LINQ and all data are correct. I'm stuck in how can I send those data to xml file and save it.

That's my first time working with text files and XML, any help will be very appreciated.

Here's the code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace TxT2XML
{
    class Program
    {
        private static void Main(string[] args)
        {
            string path = @"C:\Users\wcks\Documents\Visual Studio 2015\Projects\TxT2XML\Data_TXT_Files\";

            string[] fileEntries = Directory.GetFiles(path);

            Dictionary<string, string[]> dicData = new Dictionary<string, string[]>();

            foreach (string fileName in fileEntries)
            {
                if (!File.Exists(path))
                {
                    string[] contents = new string[100];
                    string fieldDateLogged = "Date Logged:";
                    string fieldTaskName = "Task Name:";
                    string fieldUserID = "User ID:";

                    var lines = File.ReadAllLines(fileName);
                    contents[0] = lines.Where(x => x.Contains(fieldDateLogged)).FirstOrDefault().Replace(fieldDateLogged, string.Empty).Trim();
                    contents[1] = lines.Where(x => x.Contains(fieldTaskName)).FirstOrDefault().Replace(fieldTaskName, string.Empty).Trim();
                    contents[2] = lines.Where(x => x.Contains(fieldUserID)).FirstOrDefault().Replace(fieldUserID, string.Empty).Trim();

                    XElement xElem = new XElement(fieldTaskName, dicData.Select(x => new XElement("DataLogName", new XAttribute(fieldTaskName, x.Key), new XAttribute(contents[0], x.Value))));
                    var xml = xElem.ToString();
                    Console.Write(xml);
                }
            }
        }
    }
}

class DataLogName
{
    [XmlAttribute]
    public string DataLogged { set; get; }

    [XmlAttribute]
    public string TaskName { set; get; }

    [XmlAttribute]
    public string UserID { set; get; }
}

Expected XML Output:

<DataLogName>
    <DataLogged>01-01-2017<DataLogged>
    <TaskName>Project Name<TaskName>
    <UserID>123456<UserID>
<DataLogName>

Text File sample:

            SOFTWARE DATA LOG Data Log

Date Logged:        09-29-2014 02:17:45 PM
Task Name:      PROJECT_NAME
User ID:        Administrator Mode
System:         COMPUTER_XPTO
Machine ID:     XXXXXXXX

Device:         XXXXXXXXXXXXXX
Data Source:        c:\ROOT\FOLDER\X.BIN
Sumcheck:       5DC95067
Process:        XXXXXXX/XXXXX/XXXXX/XXXXXX

Thanks a lot!


Solution

  • I would use an XmlSerializer to save to a file. An example of this is demonstrated below. The XElement makes it easier to do specific things, but for simple structures like yours, I find this approach a little cleaner.

    using System;
    using System.IO;
    using System.Xml.Serialization;
    
    namespace XmlPlayground
    {
        public class DataLogName
        {
            public DateTime DateLogged { get; set; }
            public string TaskName { get; set; }
            public string UserId { get; set; }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var fileName = "myfile.txt";
    
                // TODO: Load File from text file
                var dateLogged = DateTime.Now;
                var taskName = "Example Task";
                var userId = "Fred1";
    
                // Populate structure
                var dataToSave = new DataLogName { DateLogged = dateLogged, TaskName = taskName, UserId = userId };
    
                // Save File
                var outputFileName = Path.GetFileNameWithoutExtension(fileName);
    
                using (var outFile = File.Create($@"SomeOtherFolder\{outputFileName}.xml"))
                {
                    var formatter = new XmlSerializer(typeof(DataLogName));
                    formatter.Serialize(outFile, dataToSave);
                }
            }
        }
    }