Fantasy E-books by PhenomenalPen

XML File Saved Data One Punch Man Training App

I’m going to put all my daily records in an XML file. Hoped it can also handle a three year worth of records. I always wanted to learn how to use XML as a data storage. And for that I’m choosing XML for this project.

Desired XML File format

<Training StartOfTime=”” Rank=””>
<Progress Day=””>
<PushUps></PushUps>
<SitUps></SitUps>
<Squats></Squats>
<Jog></Jog>
</Progress>
</Training>

This is how I want my XML file to look. It’s not stored securely. This is just to make our tutorial simpler and more understandable. Post about securing XML might be posted in a different article.

Preparing to Code

I’m going to create a separate class that will handle my XML file. Putting it in a separate Class Library would be a good idea. The image below shows I added two new class library named OnePunchManTrainingAppHelper and OnePunchManTrainingAppLibrary in the project.
XML File Saved Data One Punch Man Training App Separate Classes

The helper(OnePunchManTrainingAppHelper) class library holds the class that handles XML file. Create it first by :

  • going to your projects solution explorer
  • right click on your projects name
  • and choose add → New Projects
  • in the Add New Project dialog box, select Class Library
  • and named it whatever you like or as OnePunchManTrainingAppHelper, the same as what my project has
  • create the XmlLoader class inside this new class library.

Checking and Creating Saved File

I wanted to check/load the xml saved file every time the app start. For this case I’m going to use an events, the Form.Load event. To add an event :

  • select your form(SubjectForm)
  • go to Properties window
  • select the lightning icon
  • and look for the Load event

The code below will be added to your SubjectForm.cs file,


private void SubjectForm_Load(object sender, EventArgs e) {

}

Now everytime the form(SubjectForm) appears. The Load event will be triggered. We can now call a method that will check/load the xml file inside this event. So that we know our saved file will be read every time the form is loaded.

The BeginLoadingSavedData Method


private void BeginLoadingSavedData() {
      while(!File.Exists(SavedDataPath)) {
            MessageBox.Show("Creating new saved file...", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            // create new saved data
            using (var loader = new XmlLoader()) {
                  loader.Create(SavedDataPath);
            }
            BeginLoadingSavedData();
      }
}

The File.Exists Method

File.Exists checks if a file exist. That was its name said. Putting a variable SavedDataPath as a parameter that points to the path or the name of the XML file would return a boolean value true if that file path exist and false if it isn’t. I just needed to create a string variable named SavedDataPath and assign my XML file path/name as a value. I’m adding one of the code below inside my SubjectForm class.


internal static string SavedDataPath { get; } = "OnePunchManTrainingApp.xml";

or


// (without the get accessor)
internal static string SavedDataPath = "OnePunchManTrainingApp.xml";

Again the File.Exists method will look for the file “OnePunchManTrainingApp.xml” in the app directory. We don’t need to manually create the file so lets just continue reviewing the code.

Note: We won’t discuss about the while method here. But just a simple explanation about the loop. It simply says, While our Xml file is detected false or does not exist. XmlLoader.Create method will always be called.

You might notice an error inside the using block. That is because we didn’t create the XmlLoader class methods. We can create an empty method in our XmlLoader class located in our Helper(OnePunchManTrainingAppHelper) class library but for now we will just ignore the error.

Making XmlLoader implements IDisposable

Because we called our XmlLoader inside a using block, we need to make our XmlLoader an IDisposable object. This is not necessary because XDocument and XElement classes (the classes we will be using for this project) does not implement IDisposable. The original code was not intended to use this classes so you can now omit the unnecessary codes. In your SubjectForm.cs call XmlLoader using the code below instead of the using block.

Replace the code under the comment with the code below:


// create new saved data
var loader = new XmlLoader();
      loader.Create(SavedDataPath);
BeginLoadingSavedData();

The XmlLoader Class Create Method


public void Create(string filepath) {
      DateTime startOfTime = DateTime.Now;

      try {
            xml = 
                  new XElement(rootElement,
                        new XAttribute(rootAttributesTime, startOfTime), 
                        new XAttribute(rootAttributesRank, rootAttributesRankDefaultValue),
                  new XElement(mainElement,
                        new XAttribute(mainElementAttributeDay, mainElementAttributeDayDefaultValue),
                              new XElement(subElementPushUps, subElementDefaultValue),
                              new XElement(subElementSitUps, subElementDefaultValue),
                              new XElement(subElementSquats, subElementDefaultValue),
                              new XElement(subElementJog, subElementDefaultValue)
                  ));
            xml.Save(filepath);
      } catch(Exception ex) {
            MessageBox.Show(string.Format("Problem creating data file. {0}",ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
}

Below are the varibles needed. I added all this code inside my XmlLoader class. Be sure to also add System.Xml.Linq namespace in your using directives.


private XElement xml = null;

private const string rootElement = "Training";
private const string rootAttributesTime = "StartOfTime";
private const string rootAttributesRank = "Rank";
private const string rootAttributesRankDefaultValue = "Normal";
private const string mainElement = "Progress";
private const string mainElementAttributeDay = "Day";
private const string mainElementAttributeDayDefaultValue = "1";
private const string subElementPushUps = "PushUps";
private const string subElementSitUps = "SitUps";
private const string subElementSquats = "Squats";
private const string subElementJog = "Jog";
private const string subElementDefaultValue = "0";

This XmlLoader Create method is triggered every time a saved file doesn’t exist. Remember the code loader.Create(SavedDataPath) in our SubjectForm Load event? It creates an empty XML file(“OnePunchManTrainingApp.xml” that’s what the SavedDataPath value) in our One Punch Man Training App directory that looks exactly like the format below. (The StartOfTime value will have the value of the Current Date and Time.)

<Training StartOfTime=”” Rank=”Normal”>
<Progress Day=”1″>
<PushUps>0</PushUps>
<SitUps>0</SitUps>
<Squats>0</Squats>
<Jog>0</Jog>
</Progress>
</Training>

Add a Reference using Add Reference Dialog Box

To be able to access the XmlLoader class in our helper(OnePunchManTrainingAppHelper) class library. We need to add a reference to it.
Adding a reference:

  • In the Solution Explorer, highlight the main project(OnePunchManTrainingApp)
  • right click and select Add -> Reference
  • in the Projects tab look for OnePunchManTrainingAppHelper or the class library that you wanted to add
  • then click OK

Then we add the using clause in our SubjectForm class. Open your SubjectForm.cs file and add the code below.


using OnePunchManTrainingAppHelper;

When we try to run the app, the XML file will be created in the app debug folder. You can navigate to your OnePunchManTrainingApp folder->bin->Debug to see the OnePunchManTrainingApp.xml file.

That’s it for now. Please read Designing One Punch Man Training App if you haven’t read it. Thank you and have a great day.

Leave a Reply

Your email address will not be published. Required fields are marked *