Build a Maintenance Application with the XmlTextWriter/XmlTextReader Classes

The past several articles have demonstrated how to use both the XmlTextWriter and XmlTextReader classes to perform basic XML file, or document, tasks. This article takes what you’ve seen thus far to the next logical step—creating a real application that reads and writes data using these classes.

Remember that both the XmlTextWriter and XmlTextReader classes provide for only sequential, forward-only access to an XML file. Therefore, use these classes only in situations where your application design allows for processing every node in the XML file. Examples of such scenarios are XML parsers and applications that maintain single-entity files.

Building the Demo

This article’s demo application is a C++ mixed-mode (native and managed code) example of maintaining a single-entity file, where the information for each movie video is stored in an individual file. If the application were storing the information for all videos in the same file, using the .NET XML DOM (Document Object Model) classes would be best, because they allow direct access to specific nodes without having to process each of the file’s nodes from beginning to end. (Upcoming articles will explore the .NET implementation of the XML DOM.)

The following steps walk you through creating the demo application:

  1. Create an MFC dialog-based application called VideoInfo.
  2. From the Project Settings, specify the option Use Managed Extensions.
  3. Open the stdafx.hfile and add the following to the end of the file:
    ...
    
    #using <mscorlib.dll>
    #using <System.Windows.Forms.dll>
    #using <System.dll>
    #using <System.xml.dll>
    #using <Microsoft.VisualBasic.dll>
    
    using namespace System;
    using namespace System::Windows::Forms;
    using namespace System::Xml;
    using namespace System::IO;
    using namespace Microsoft::VisualBasic;
    #undef MessageBox
    

    (You’ll see shortly the purpose for the Microsoft.VisualBasic assembly.)

  4. Open the dialog template resource and add the controls as you see them in Figure 1.

    Figure 1: Dialog Template Resource Layout for the Demo Application

  5. Hard code two entries into the Format combobox control’s Data property: “DVD;VHS” (without the quotes).
  6. Set the Actors listbox Sort property to True.
  7. Set up the DDX variables as listed in Table 1.

    Table 1: DDX Variables to Be Used in Demo

    Control Variable Type Variable Name
    Format edit CString m_strFormat
    Title edit CString m_strTitle
    Director edit CString m_strDirector
    Actors listbox CListBox m_lbxActors
    Studio edit CString m_strStudio
    Release edit int m_iReleaseYear
    Runtime edit int m_iRuntime
  8. Add a dialog member variable that will hold the value of the application folder:
    class CVideoInfoDlg : public CDialog
    {
    ...
      CString m_strWorkingDir;
    
  9. Add the following code to set the m_strWorkingDir member just before the end of the dialog’s OnInitDialogfunction:
    TCHAR buff[MAX_PATH];
    GetModuleFileName(NULL, buff, MAX_PATH);
    m_strWorkingDir = Path::GetDirectoryName(buff);
    
  10. As the dialog box’s listbox and Add button indicate, the application allows for the entry of multiple actors to each video definition. If you’re a veteran MFC developer, you’re accustomed to having to create a dialog box any time a value is needed from the user. However, because this is a mixed-mode application (giving access to the full .NET class library) and Microsoft ported the VB 6 InputBoxfunction for backwards compatibility between VB 6 and VB.NET, you also have access to it from C++. Therefore, you can obtain a single value from the user with one line of code.

    Add an event handler for the dialog box’s Add button and code it as follows:

    void CVideoInfoDlg::OnBnClickedAddActor()
    {
      CRect rect;
      GetWindowRect(&rect);
      String* actor =
        Interaction::InputBox(S"Enter the Actor name and click the
                                OK button:",
                              S"New Actor",
                              S"",
                              rect.left + (rect.Width() / 2),
                              rect.top + (rect.Height() / 2));
      if (actor->Length)
      {
        if (LB_ERR ==
          m_lbxActors.FindStringExact(-1, (CString)actor))
          m_lbxActors.AddString((CString)actor);
        else
          MessageBox::Show(S"That actor is already listed");
      }
    }
    
  11. Now, add the following function to allow the removal of the currently selected actor in the listbox.

    Note:The Add/Remove Actor functions have nothing to do with XML, but they’re small bits of code that help to create a more practical application from which to learn XML.

    void CVideoInfoDlg::OnBnClickedRemoveActor()
    {
      int iCurrSel;
      if (LB_ERR == (iCurrSel = m_lbxActors.GetCurSel()))
      {
        MessageBox::Show(S"Please select an actor to remove");
      }
      else
      {
        m_lbxActors.DeleteString(iCurrSel);
      }
    }
    

More by Author

Must Read