Click here to Skip to main content
15,881,281 members
Articles / Desktop Programming / MFC
Article

CMarkupArchive, an extension to CMarkup

Rate me:
Please Sign up or sign in to vote.
4.00/5 (7 votes)
13 Oct 20023 min read 375.6K   1.5K   58   45
This class adds additional features to the XML parser CMarkup: file handling, namespaces, numerical helpers and new find methods.

Sample Image - markuparchive.png

CMarkup is powerful XML parser posted on CodeProject (see article here). It is fast and intuitive. Here I introduce a derived class of CMarkup called CMarkupArchive that adds even more features. You can derive it from free CMarkup Lite (found here at http://www.codeproject.com/soap/markupclass.asp) or from CMarkup Evaluation (found at www.firstobject.com with licensing options explained there). All the addition are encapsulated in code of CMarkupArchive and CMarkup is left unchanged. The main features of this extension are:

  • File handling for loading/storing data with zipping support (using zlib),
  • CArchive style, get rid of your old Serialize functions and use XML instead!
  • New find method : Find(Child)ElemAttrib, find an element matching a tag, containing an attribute matching a desired value,
  • Adding and Getting helper functions: add/get numerical values without bothering about string conversion! All the classical types are supported : bool, int, UINT, double,, std::vector, std::list and std::valarray.
  • Find and get helper functions: find a tag, and load numerical value if needed.
  • Namespace support: automatically append a namespace to the tags.

The article does not contain any demo but only the source code. To get a demo, try the one shipped with CMarkup article.

File Handling and CArchive style

CMarkupArchive will do the dirty work of handling files for you. Just specify the filename, open it and you're ready to parse:

// CMarkupArchive is in the markup namespace
using namespace markup;
CMarkupArchive xml( /* flags */ ArchiveModeNotZipped /* Disabling zipping */ | 
                                ArchiveModeStoring /* Storing mode*/);
    
    // Try to open file for writing
    if ( xml.Open(_T("myXMLfile.xml"))
    {
        // file succesfully opened, insert parsing code



        // closing
        xml.Close();
    }

It uses zlib for in-code zipping, unzipping of XML. However you can disable this option by using the corresponding flag (see above). The state of the archive can be retrieved using classical functions like IsStoring,

IsLoading
and IsOpen.

New find method

bool FindElemAttrib( LPCTSTR szName, LPCTSTR szAttrib, LPCTSTR szAttribValue );
bool FindChildElemAttrib( LPCTSTR szName , LPCTSTR szAttrib, LPCTSTR szAttribValue );

With this method, you can find a (child) element matching szName, containing an attribute szAttrib matching the value szAttribValue.

Here's a typical example of application. Consider the following piece of XML:

<employe name="Jack">
    ...
</employe>
<employe name="Bill">
    ...
</employe>

Finding the employe name Bill is a piece of cake:

if( xml.FindChildElemAttrib( _T("employe") , _T("name"), _T("Bill") ))
{
    // found employe Bill
}

Numerical values helpers

Stop bothering about converting numerical values to string or the inverse. A whole set of helper functions is available.

Storing data

bool AddElemEx(LPCTSTR szName, Type _Type );
bool AddChildElemEx(LPCTSTR szName, Type _Type );
bool AddAttribEx(LPCTSTR szName, bool _Type);
bool AddChildAttribEx(LPCTSTR szName, bool _Type);

where type is one of the following: bool, int, UINT, DWORD, float, double,

std::vector<double-float-int-BYTE>
, std::list<double-float-int-BYTE>, std::valarray<double-float-int-BYTE>. They use Add(...) from CMarkup.

A typical example is:

bool correct;
double value;
...
xml.AddChildElemEx(_T("Corret"), correct);
xml.AddChildAttribEx(_T("Value"), value);

Loading data

To load data, use the following

Type GetData[Type]();
Type GetChildData[Type]();
Type GetAttribData[Type](LPCTSTR szAttrib);
Type GetChildAttribData[Type](LPCTSTR szAttrib);

These functions are the duals of the storing helper functions and use Get(...)Data from CMarkup.

Other specialized function do the following: find element and get the data if found:

bool FindGetData(LPCTSTR szName, Type& _Type);
bool FindGetChildData(LPCTSTR szName, Type& _Type);

Typical use will look like

bool correct;
double value;
...
xml.FindGetElem(_T("Corret"), correct);
xml.FindGetChildElem(_T("Value"), value);

Namespace handling

You can add namespace automatically to your tags by using the following (self-explanatory) functions:

bool SetNameSpace(LPCTSTR szNameSpace);
CString GetNameSpace() const;

The following piece of code

...
xml.SetNameSpace(_T("myNameSpace"));
...
xml.AddChildElem(_T("element"), _T("..."));

will output

<myNameSpace:element>
    ...
</myNameSpace:element>

Encoding string

You can modifiy the xml encoding string: when saving to a file or string, the following line is added:

<?xml version="1.0" encoding="ISO-8859-1" ?>
The value ISO-8859-1 can be modified using SetEncodingString.

Integrating CMarkupArchive in your existing projects

CMarkupArchive is inherited from CMarkup and therefore you can use it in any project using CMarkup even if you're working with version other than Lite! The source comes as a static libary. Here are the installation steps:

  1. Copy your version of CMarkup in the XMLMarkup directory,

  2. Integrate them into the static library project,

  3. Enclose the CMarkup declaration and implementation in the markup namespace,

  4. Declare as virtual the following functions in CMarkup declaration (needed for namespace handling):

    virtual bool AddElem( LPCTSTR szName, LPCTSTR szData=NULL);
    virtual bool AddChildElem( LPCTSTR szName, LPCTSTR szData=NULL);
    virtual bool FindElem( LPCTSTR szName=NULL);
    virtual bool FindChildElem( LPCTSTR szName=NULL);
    
  5. Recompile the static library. It should output an XMLParser(d,u,ud).lib (respectively for release, debug, UNICODE debug and UNICODE release),

  6. Include MarkupArchive.h in your projects where it's needed. As it is given as a static library, the header will automatically tell the linker to look for the .lib (make sure they are in the path).

  7. Parse and parse again.

Update History

10-14-2002

  • Fixed a bug when trying to open a non-existing file
  • Added STL2String template to handle string to stl and stl to string conversions
  • Fixed some bugs about namespaces

10-10-2002

  • A lot of contributions from Albert van Peppen,
  • Changed Add(Child)(Attrib-Elem)[Type] to Add(Child)(Attrib-Elem)Ex, better and easier, AVP,
  • Added list and valarray support,
  • Fixed bugs in Find(Child)ElemAttrib
  • Move EArchive enum into the class, - Added namespace markup

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer
United States United States
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

Comments and Discussions

 
QuestionLicense Pin
Member 896106528-May-12 23:07
Member 896106528-May-12 23:07 
GeneralSeveral free/Small XML parser Pin
maplewang20-Oct-10 22:03
maplewang20-Oct-10 22:03 
GeneralUsing GetAttribEx Pin
alerma9-Dec-03 6:07
alerma9-Dec-03 6:07 
GeneralRe: Using GetAttribEx Pin
Jonathan de Halleux9-Dec-03 6:16
Jonathan de Halleux9-Dec-03 6:16 
GeneralRe: Using GetAttribEx Pin
alerma9-Dec-03 6:42
alerma9-Dec-03 6:42 
GeneralStylesheets... Pin
Joel Holdsworth22-Mar-03 4:48
Joel Holdsworth22-Mar-03 4:48 
GeneralYes Pin
Jonathan de Halleux22-Mar-03 5:41
Jonathan de Halleux22-Mar-03 5:41 
QuestionIs it possible to compile an STL version of this library? Pin
smt525-Mar-03 14:07
smt525-Mar-03 14:07 
AnswerAsk the real author... Pin
Jonathan de Halleux5-Mar-03 14:21
Jonathan de Halleux5-Mar-03 14:21 
GeneralRe: Ask the real author... Pin
smt525-Mar-03 16:16
smt525-Mar-03 16:16 
GeneralOpening an existing file Pin
martinec15-Jan-03 9:45
martinec15-Jan-03 9:45 
Generalanother question Pin
onepence28-Oct-02 15:26
onepence28-Oct-02 15:26 
GeneralRe: Is it a CMarkup problem? Pin
onepence28-Oct-02 14:39
onepence28-Oct-02 14:39 
GeneralNot the right forum Pin
Jonathan de Halleux6-Nov-02 8:33
Jonathan de Halleux6-Nov-02 8:33 
Generala slight problem need help Pin
onepence24-Oct-02 18:40
onepence24-Oct-02 18:40 
GeneralIs it a CMarkup problem? Pin
Jonathan de Halleux24-Oct-02 23:08
Jonathan de Halleux24-Oct-02 23:08 
GeneralRe: Is it a CMarkup problem? Pin
onepence27-Oct-02 19:52
onepence27-Oct-02 19:52 
GeneralSlight problem detected Pin
Joel Holdsworth18-Sep-02 10:23
Joel Holdsworth18-Sep-02 10:23 
GeneralRe: Slight problem detected Pin
Albert van Peppen19-Sep-02 5:26
professionalAlbert van Peppen19-Sep-02 5:26 
GeneralWill be done Pin
Jonathan de Halleux19-Sep-02 5:37
Jonathan de Halleux19-Sep-02 5:37 
GeneralFinally Pin
Jonathan de Halleux13-Oct-02 21:17
Jonathan de Halleux13-Oct-02 21:17 
GeneralRe: Finally Pin
Albert van Peppen13-Oct-02 23:10
professionalAlbert van Peppen13-Oct-02 23:10 
GeneralUpdated again... Pin
Jonathan de Halleux14-Oct-02 22:42
Jonathan de Halleux14-Oct-02 22:42 
GeneralRe: Updated again... Pin
Albert van Peppen14-Oct-02 23:37
professionalAlbert van Peppen14-Oct-02 23:37 
GeneralRe: Updated again... Pin
Albert van Peppen15-Oct-02 0:10
professionalAlbert van Peppen15-Oct-02 0:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.