Click here to Skip to main content
Click here to Skip to main content

Fast Xml Utility

, 31 Mar 2008 GPL3
Rate this:
Please Sign up or sign in to vote.
A fast utility to deal with xml

Introduction

A fast utility to deal with xml.

Background

When you want to create such a xml file to describe you struct:

<?xml version="1.0" encoding="UTF-8" ?>
- <Body>
- <Item>
< <szContactListName>item1</szContactListName>
<szContactListPath>D:\asdsad.txt</szContactListPath>
<dwContactNum>2</dwContactNum>
<CreateTime>1206964933</CreateTime>
</Item>
<Item>
< <szContactListName>item2</szContactListName>
<szContactListPath>D:\22.txt</szContactListPath>
<dwContactNum>6</dwContactNum>
<CreateTime>1206963246</CreateTime>
</Item>
... ...
</Body>
and when you need to create 10+ this xmls, did you think to do something
to reduce the work?
CXMLFileCommon is designed for this.

Using the code

Code of CXMLFileCommon.h

/*




XML File Common
XMLFileCommon.h
*/



#ifndef __XMLFILECOMMON_H__
#define __XMLFILECOMMON_H__
#include <span class="code-string">"list"</span>
using namespace std;
#include <span class="code-string">"assert.h"</span>
#include <span class="code-string">"atlbase.h"</span>
#include <span class="code-string">"atlconv.h"</span>
#include <span class="code-string">"msxml.h"</span>
#pragma  comment(lib, "msxml2.lib")
#pragma warning(disable : 4786)
template <class T, class P>
class __declspec(novtable) CXMLFileCommon
{
public:
 enum XMLOPERATION
 {
  xml_add = 0,
  xml_modify,
  xml_del,
  xml_getall,
  xml_getfirstmatch
 };
protected:
 struct XMLNODEINFO
 {
  TCHAR* szNode;
  TCHAR* szValueType;
  int  nOffset;
 };
#define BEGIN_XML_MAP() \
 static const XMLNODEINFO* _XMLMap() \
 { \
 static const XMLNODEINFO _XmlNodeMap[] = \
 { 
#define XML_MAP(Node, ValueType, s) \
 {_T(#Node), _T(#ValueType), offsetof(s, Node)}, \
#define END_XML_MAP() \
 {NULL, NULL, 0} \
 }; \
 \
 return &_XmlNodeMap[0];  \
 } 
 CString GetValue(CString szValueType, DWORD Address)
 {
  CString szValue;
  if ( szValueType == _T("CString") )
  {
   szValue = *(CString*)Address;
   return szValue;
  }
  if ( szValueType == _T("DWORD") )
  {
   szValue.Format(_T("%d"), *(DWORD*)Address);
   return szValue;
  }
  if ( szValueType == _T("BOOL") )
  {
   szValue.Format(_T("%d"), *(DWORD*)Address);
   return szValue;
  }
  if ( szValueType == _T("time_t") )
  {
   szValue.Format(_T("%ld"), *(time_t*)Address);
   return szValue;
  }
  if ( szValueType == _T("ULONG") )
  {
   szValue.Format(_T("%ld"), *(ULONG*)Address);
   return szValue;
  }
  if ( szValueType == _T("int") ) 
  {
   szValue.Format(_T("%d"), *(int*)Address);
   return szValue;
  }
  if ( szValueType == _T("UINT64") ) 
  {
   szValue.Format(_T("%ld"), *(UINT64*)Address);
   return szValue;
  }
  assert(0);
  // Struct item type UnSupport.
  return szValue;
 }
 BOOL SetValue(CString szValueType, DWORD Address, CString szValue)
 {
  USES_CONVERSION;
  if ( szValueType == _T("CString") )
  {
   *(CString*)Address = szValue;
   return TRUE;
  }
  if ( szValueType == _T("DWORD") )
  {
   *(DWORD*)Address = atol(T2A(szValue.GetString()));
   return TRUE;
  }
  if ( szValueType == _T("BOOL") )
  {
   *(BOOL*)Address = atol(T2A(szValue.GetString()));
   return TRUE;
  }
  if ( szValueType == _T("time_t") )
  {
   *(time_t*)Address = _atoi64(T2A(szValue.GetString()));
   return TRUE;
  }
  if ( szValueType == _T("ULONG") )
  {
   *(ULONG*)Address = atol(T2A(szValue.GetString()));
   return TRUE;
  }
  if ( szValueType == _T("int") )
  {
   *(int*)Address = atoi(T2A(szValue.GetString()));
   return TRUE;
  }
  if ( szValueType == _T("UINT64") ) 
  {
   *(UINT64*)Address = _atoi64(T2A(szValue.GetString()));
   return TRUE;
  }
  assert(0);
  // Struct item type UnSupport.
  return FALSE;
 }
 BOOL Get(CComPtr<IXMLDOMNode> pNode,  T& t)
 {
  USES_CONVERSION;
  // pNode is "Item"
  if ( pNode == NULL )
   return FALSE;
  const XMLNODEINFO* pMap = P::_XMLMap();
  for (int i = 0; pMap[i].szNode != _T('\0'); i++ )
  {
   CString szNode = pMap[i].szNode;
   CString szValueType = pMap[i].szValueType;
   CString szValue;
   CComPtr<IXMLDOMNode> __spNode = NULL;
   if ( FAILED(pNode->selectSingleNode(CComBSTR(szNode), &__spNode)) || __spNode == NULL )
    return FALSE;
   BSTR bstr;
   if ( __spNode )
   {
    __spNode->get_text(&bstr);
    szValue = OLE2T(bstr);
   }
   DWORD dwAddress = (DWORD)&t+(DWORD)pMap[i].nOffset;
   if ( IsBadReadPtr((void*)dwAddress, 1) )
    return FALSE;
   if ( !SetValue(szValueType, dwAddress, szValue) )
    return FALSE;
  }
  return TRUE;
 }
 BOOL Add(CComPtr<IXMLDOMNode> pNode,  T& t)
 { 
  // pNode is "Item"
  if ( pNode == NULL )
   return FALSE;
  const XMLNODEINFO* pMap = P::_XMLMap();
  for (int i = 0; pMap[i].szNode != _T('\0'); i++ )
  {
   CString szNode = pMap[i].szNode;
   CString szValueType = pMap[i].szValueType;
   CString szValue;
   DWORD dwAddress = (DWORD)&t+(DWORD)pMap[i].nOffset;
   if ( IsBadReadPtr((void*)dwAddress, 1) )
    return FALSE;
   szValue = GetValue(szValueType, dwAddress);
   CComPtr<IXMLDOMNode> pNodeSub = NULL;
   if ( FAILED(pNode->selectSingleNode(CComBSTR(szNode), &pNodeSub)) )
    return FALSE;
   if ( !pNodeSub )
   {
    CComPtr<IXMLDOMElement> _spNode;
    if ( FAILED(m_spxmlDoc->createElement(CComBSTR(szNode), &_spNode)) || _spNode == NULL )
     return FALSE;
    if ( FAILED(pNode->appendChild(_spNode, NULL)) )
     return FALSE;
    pNodeSub = _spNode;
   }
   if ( pNodeSub )
   {
    if ( FAILED(pNodeSub->put_text(CComBSTR(szValue)) ) )
     return FALSE;
   }
  }
  return Save();
 }
public:
 CXMLFileCommon() 
 {  
  m_spxmlDoc  = NULL;
  m_szItemTag = _T("Item");
  m_szBodyTag = _T("Body");
  m_szComment = _T("Author: wak 2008.03.25");
  m_szEncode = _T("UTF-8");
 }
 void SetParams(
  CString szComment = _T("Xml by wak."),
  CString szEncode  = _T("UTF-8"),
  CString szItemTag = _T("Item"),
  CString szBodyTag = _T("Body") )
 {
  m_szBodyTag = szBodyTag;
  m_szItemTag = szItemTag;
  m_szEncode = szEncode;
  m_szComment = szComment;
 }
 ~CXMLFileCommon() { Release(); }
 BOOL Load()
 {
  USES_CONVERSION;
  // 
  // Init IXMLDOMDocument
  //
  assert( m_spxmlDoc == NULL );
  if ( FAILED(m_spxmlDoc.CoCreateInstance(CLSID_DOMDocument)) || m_spxmlDoc == NULL )
   return FALSE;
  if ( FAILED(m_spxmlDoc->put_async(VARIANT_FALSE)) )
   return FALSE;
  VARIANT_BOOL vbool;
  COleVariant vVar(m_szXmlFile);
  if ( FAILED(m_spxmlDoc->load(vVar, &vbool)) || vbool == VARIANT_FALSE )
   return FALSE;
  return TRUE;
 }
 BOOL Release()
 {
  if ( m_spxmlDoc )
  {
   m_spxmlDoc.Release();
   m_spxmlDoc = NULL;
  }
  return TRUE;
 }
 void SetXmlName(CString szFileName)
 {
  m_szXmlFile = szFileName;
  assert(!m_szXmlFile.IsEmpty());
 }
 BOOL InitXML(BOOL bOverWrite = FALSE)
 {
  USES_CONVERSION;
  assert(!m_szXmlFile.IsEmpty());
  CComPtr<IXMLDOMDocument> spIXMLDoc;
  if ( FAILED(spIXMLDoc.CoCreateInstance(CLSID_DOMDocument)) || spIXMLDoc == NULL )
   return FALSE;
  if ( FAILED(spIXMLDoc->put_async(VARIANT_FALSE)) )
   return FALSE;
  if ( ::GetFileAttributes(m_szXmlFile) != -1 )
  {
   VARIANT_BOOL vbool;
   COleVariant vVar(m_szXmlFile);
   if ( SUCCEEDED(spIXMLDoc->load(vVar, &vbool)) && vbool == VARIANT_TRUE  && !bOverWrite )
   {
    spIXMLDoc.Release();
    return TRUE;
   }
  }
  CComPtr<IXMLDOMProcessingInstruction> spProcessingInstruction;
  CString szTmp;
  szTmp.Format(_T("version=\"1.0\"  encoding=\"%s\""), m_szEncode);
  if ( SUCCEEDED(spIXMLDoc->createProcessingInstruction(
   CComBSTR(_T("xml")), 
   CComBSTR(szTmp), 
   &spProcessingInstruction)) && spProcessingInstruction )
  {
   spIXMLDoc->appendChild(spProcessingInstruction, NULL);
  }
  CComPtr<IXMLDOMComment > spComment;
  spIXMLDoc->createComment(CComBSTR(m_szComment), &spComment);
  spIXMLDoc->appendChild(spComment, NULL);
  CComPtr<IXMLDOMElement> spElementTop;
  spIXMLDoc->createElement(CComBSTR(m_szBodyTag), &spElementTop);
  spIXMLDoc->appendChild(spElementTop, NULL);
  COleVariant vpath(m_szXmlFile);
  if ( FAILED(spIXMLDoc->save(vpath)) )
   return FALSE;
  spIXMLDoc.Release();
  return TRUE;
 }
 BOOL Save()
 {
  USES_CONVERSION;
  assert( m_spxmlDoc );
  COleVariant vpath(m_szXmlFile);
  if ( FAILED(m_spxmlDoc->save(vpath)) )
   return FALSE;
  return TRUE;
 }
 BOOL XmlOperation(
  T& t, 
  XMLOPERATION fOp, 
  list<T>* pAllItemList = NULL,
  BOOL bSave = FALSE)
 {
  USES_CONVERSION;
  /************************************************************************/
  /* Because the first one of the struct is used to find.                 */
  /************************************************************************/
  const XMLNODEINFO* pMap = P::_XMLMap();
  assert ( pMap && pMap[0].szNode != NULL );
  CString szNode = pMap[0].szNode;
  CString szValueType = pMap[0].szValueType;
  assert ( szValueType == _T("CString") );
  if ( fOp == xml_getall && !pAllItemList )
  {
   assert(pAllItemList);
   return FALSE;
  }
  CComPtr<IXMLDOMNode> spNode;
  if ( FAILED(m_spxmlDoc->selectSingleNode(CComBSTR(m_szBodyTag), &spNode)) || spNode == NULL )
   return FALSE;
  CComPtr<IXMLDOMNodeList> spNodeList;
  if ( FAILED(spNode->selectNodes(CComBSTR(m_szItemTag), &spNodeList)) || spNodeList == NULL )
   return FALSE;
  long count = 0;
  spNodeList->get_length(&count);
  BOOL bFind = FALSE;
  CComPtr<IXMLDOMNode> _spNode = NULL;
  for ( int i = 0; i < count; i++ )
  {
   if ( SUCCEEDED(spNodeList->get_item(i, &_spNode)) && _spNode != NULL )
   {
    if ( fOp == xml_getall )
    {
     T t1;
     if ( Get(_spNode, t1) )
      pAllItemList->push_back(t1);
    }
    else
    {
     CComPtr<IXMLDOMNode> __spNode = NULL;
     if ( FAILED(_spNode->selectSingleNode(CComBSTR(szNode), &__spNode)) || __spNode == NULL )
      return FALSE;
     BSTR bstr;
     if ( __spNode )
     {
      __spNode->get_text(&bstr);
      if ( *(CString*)&t == OLE2T(bstr) )
      {
       bFind = TRUE;
       break;
      }
     }
    }
    _spNode.Release();
   }
  }
  if ( fOp == xml_getall )
  {
   return TRUE;
  }
  switch ( fOp )
  {
  case xml_del:
   {
    if ( !bFind )
     return FALSE;
    return ( SUCCEEDED(spNode->removeChild(_spNode, NULL)) && Save() );
   }
   break;
  case xml_add:
  case xml_modify:
   {
    if ( !bFind || fOp != xml_modify )
    {
     CComPtr<IXMLDOMElement> spElement;
     if ( FAILED(m_spxmlDoc->createElement(CComBSTR(m_szItemTag), &spElement)) || spElement == NULL )
      return FALSE;
     if ( FAILED(spNode->appendChild(spElement, NULL)) )
      return FALSE;
     _spNode = spElement;
    }
    return Add(_spNode, t);
   }
   break;
  case xml_getfirstmatch:
   {
    return Get(_spNode, t);
   }
   break;
  default:
   {
    return FALSE;
   }
   break;
  }
  return TRUE;
 }
protected:
 CString m_szXmlFile;
 CComPtr<IXMLDOMDocument> m_spxmlDoc;
 CString m_szItemTag;
 CString m_szBodyTag;
 CString m_szComment;
 CString m_szEncode;
};
#endif  // __XMLFILECOMMON_H__

When you create a new xml file use like this:

 
/*


Contact List XML
ContactListXml.h




*/







#ifndef __CONTACTLISTXML_H__
#define __CONTACTLISTXML_H__

#include <span class="code-string">"XMLFileCommon.h"</span>
typedef struct tagCONTACTLISTINFO
{
 CString szContactListName;
 CString szDescription;
 CString szContactListPath;
 DWORD  dwContactNum;
 time_t CreateTime;
}CONTACTLISTINFO, *PCONTACTLISTINFO;



class CContactListXml 
 : public CXMLFileCommon<CONTACTLISTINFO, CContactListXml>
{
public:
 CContactListXml() {};
 ~CContactListXml() {};

public:
 BEGIN_XML_MAP()
  XML_MAP(szContactListName, CString, CONTACTLISTINFO)
  XML_MAP(szDescription, CString, CONTACTLISTINFO)
  XML_MAP(szContactListPath, CString, CONTACTLISTINFO)
  XML_MAP(dwContactNum, DWORD, CONTACTLISTINFO)
  XML_MAP(CreateTime, time_t, CONTACTLISTINFO)
 END_XML_MAP()
};




#endif  __CONTACTLISTXML_H__
 CContactListXml xml;
 xml.SetXmlName("C:\\2.xml");
 xml.SetParams("pppasdsdasdp", "UTF-8");
 if ( xml.InitXML() && xml.Load() )
 {
  CONTACTLISTINFO cti;
  cti.szContactListName = _T("我是wak");
  cti.szDescription = _T("Xml很好");
  cti.szContactListPath = _T("你撒谎的哦");
  cti.dwContactNum = 1002;
  cti.CreateTime = 213244;
  
  xml.XmlOperation(cti, CContactListXml::xml_modify);
  xml.XmlOperation(cti, CContactListXml::xml_add);
  list<CONTACTLISTINFO> list1;
  xml.XmlOperation(cti, CContactListXml::xml_findfirstmatch, &list1);
  
  CONTACTLISTINFO d3;
  d3.szContactListName = "pppp3";
  xml.XmlOperation(cti, CContactListXml::xml_findfirstmatch);
 }

I hope this code may help you much. If you have any question can tell me.

wak 2008.3.31 22:05

History

NULL

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

wak1984
Software Developer PPStream
China China
Wak has been programming professionally for three years now.
 
Worked for ROR SOFT
Worked for www.qihoo.com
Worked for PPstream
 
And... I want to work for MicroSoft someday ^_^

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.141015.1 | Last Updated 31 Mar 2008
Article Copyright 2008 by wak1984
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid