The INI file is the old Windows standard for keeping program settings, preferences and configurations. Here is an example of an INI file. Each section starts with a bracketed section name and has a list of key=value entries.
[Settings] Count=10 User=John Smith [Files] Database=test2.txt
Here is an example XML format to contain the same information. You might want to use the section names and entry names (keys) as tag names in your XML format, but if there is any chance your section and entry names will contain spaces or symbols then its better to put them in attributes since spaces and certain symbols are not allowed in XML tag names.
<Settings>
<Section name="Settings">
<Entry name="Count">10</Entry>
<Entry name="User">John Smith</Entry>
</Section>
<Section name="Files">
<Entry name="Database">test2.txt</Entry>
</Section>
</Settings>
The nice thing about using XML is that your types of data in the future won't be limited to simple entries. You can later introduce entries containing lists of elements and entries containing persisted objects, or even additional entry attributes such as timestamps and modified flags.
You can use the following SetEntry
and FindEntry
methods much like you use the Win32 functions WritePrivateProfileString
and GetPrivateProfileString
. They should be implemented in your own program, not as members of the CMarkup class itself, because they are likely to be modified to conform to your needs. Here is sample code that uses the functions on the above INI-style example.
CMarkup xml; SetEntry( xml, "Settings", "Count", "10" ); SetEntry( xml, "Settings", "User", "John Smith" ); SetEntry( xml, "Files", "Database", "test1.txt" ); SetEntry( xml, "Files", "Database", "test2.txt" ); // overwrite CString csUser; ASSERT( FindEntry(xml,"Settings","User",csUser) ); ASSERT( csUser == "John Smith" );
Here are sample SetEntry
and FindEntry
function implementations.
void SetEntry( CMarkup& xml, CString csSection, CString csEntry, CString csValue ) { // Find/Create root element of xml document xml.ResetPos(); // Put your root element name here if ( ! xml.FindElem() ) xml.AddElem( "Settings" ); // Find/Create section BOOL bFoundSection = FALSE; while ( xml.FindChildElem("Section") ) { // Is this the right section? if ( xml.GetChildAttrib("name") == csSection ) { bFoundSection = TRUE; break; } } if ( ! bFoundSection ) { xml.AddChildElem( "Section" ); xml.SetChildAttrib( "name", csSection ); } // Find/Create entry xml.IntoElem(); BOOL bFoundEntry = FALSE; while ( xml.FindChildElem("Entry") ) { // Is this the right entry? if ( xml.GetChildAttrib("name") == csEntry ) { bFoundEntry = TRUE; break; } } if ( ! bFoundEntry ) { xml.AddChildElem( "Entry" ); xml.SetChildAttrib( "name", csEntry ); } // Set value xml.SetChildData( csValue ); } bool FindEntry( CMarkup& xml, CString csSection, CString csEntry, CString& csValue ) { // Loop through sections xml.ResetPos(); while ( xml.FindChildElem("Section") ) { // Is this the right section? if ( xml.GetChildAttrib("name") == csSection ) { // Check entries in this section xml.IntoElem(); while ( xml.FindChildElem("Entry") ) { // Is this the right entry? if ( xml.GetChildAttrib("name") == csEntry ) { csValue = xml.GetChildData(); return TRUE; } } break; // don't check any other sections } } return FALSE; }