• 利用XML文件的一个写日志的类!!!!!


    对于程序执行期间的错误跟踪!相信大家都有自己的一套办法!!!但都是利用文件文件,我这次利用的是XML&XSL,可产生报表格式的日志,轻松生成报表!!!

    我参考了Emilio Guijarro Cameros的CXMLProfile写XML配置文件的思想!!!利用XML 接口IXMLDOMDocumentIXMLDOMNodeIXMLDOMElement和 MFC相结合,写成了一个CXMLLogfile类,只暴露了两个公共方法

     void Log(LPCTSTR lpszFilName,LPCTSTR s,...);
     bool ClearAll()

    Log是添加一条日志,ClearAll是清除所有日志!!!当大家需要查看日值时,只需要打开相应的XML文件Log.XML就可以看到一个日志表格了,为此我专门写了一个XSL样式文件(XML样式XSL文件必须在XML文件同一目录下)!

    以下是源代码,需要IE5.5以上支持!!!如果编译错误!请下载微软的最新XML SDK!!!!


    // XMLLogfile.h: interface for the CXMLLogfile class.
    //
    //////////////////////////////////////////////////////////////////////

    #if !defined(AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__INCLUDED_)
    #define AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include
    #include
    #include
    #include
    #include

    //Author : By force eagle
    //Date time : 2003-5-26 17:08
    //reference :
    //    CXMLProfile By Emilio Guijarro Cameros

    #pragma comment(lib,"msxml2.lib")
    class CXMLLogfile : public CObject 
    {
     CString m_strFileName;
     IXMLDOMDocument *m_pXMLDoc;
     
     IXMLDOMNode * GetChildNode(LPCTSTR lpszParent, LPCTSTR lpszChild,BOOL bCreate = TRUE);
     IXMLDOMNode * GetFirstLevelNode(LPCTSTR lpszNodeName,BOOL bCreate = TRUE);

     // UNIX timestamp: seconds from 1970-01-01 00:00:00 (UTC)
     inline double TimeStamp(void)
     {
      _timeb ts;
      _ftime( &ts );
      return (int)ts.time + (ts.millitm/1000.0);
     };
    protected:
     void AppendNode(IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue);
     void AppendItem(LPCTSTR lpszFileName,LPCTSTR lpszComment);

     void Flush();

     bool CreateLogFile(LPCTSTR lpszLogFilName);

     void DumpComError(_com_error &e);

     void Init();


    public:
     CXMLLogfile(LPCTSTR lpszFileName = NULL);
     virtual ~CXMLLogfile();
     void Log(LPCTSTR lpszFilName,LPCTSTR s,...);
     bool ClearAll();
    };

    #endif // !defined(AFX_XMLLOGFILE_H__EA8ACC84_7139_49F6_9B8A_F69D9CF5C385__INCLUDED_)


    // XMLLogfile.cpp: implementation of the CXMLLogfile class.
    //
    //////////////////////////////////////////////////////////////////////

    #include "stdafx.h"
    #include "XMLLogfile.h"

    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    /*
    static TCHAR *szLogOrig= {_T("/n"
     "/n"
     "/nXXXX/n1053925276.381/n"
     "2003-05-26/n13:01:16.861/n/n")};
    //*/
    static WCHAR *wszLogOrig = {L"/n/n/nXXXX/n1053925276.381/n2003-05-26/n13:01:16.861/n/n"};

    CXMLLogfile::CXMLLogfile(LPCTSTR lpszFileName)
    {
     VARIANT_BOOL bResult;
     IXMLDOMElement *pRootNode;
     HRESULT hr;
     if (NULL == lpszFileName)
     {
      CString strHlpPath ,strAppName;
      strHlpPath = AfxGetApp()->m_pszHelpFilePath;
      strAppName = AfxGetAppName();
      strHlpPath = strHlpPath.Left(strHlpPath.GetLength() - 4
       - strAppName.GetLength());
      m_strFileName = strHlpPath + _T("LOG.XML");
     }
     else
     {
      m_strFileName = lpszFileName;
     }

     hr = CoInitialize(NULL);
    LoadLog:
     if(SUCCEEDED(hr))
     {
      hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
       IID_IXMLDOMDocument, (void**)&m_pXMLDoc);
      if(SUCCEEDED(hr))
      {
       m_pXMLDoc->load(COleVariant(m_strFileName), &bResult);
      }
     }

     //取得根节点
     m_pXMLDoc->get_documentElement(&pRootNode);

     if(pRootNode == NULL) //无根节点
     {
      m_pXMLDoc->Release();
      m_pXMLDoc = NULL;
      //重新创建XML日值文件
      CreateLogFile(m_strFileName);
      goto LoadLog; //重新载入
     }
     else
     {
      Init();
     }
    }

    CXMLLogfile::~CXMLLogfile()
    {
     m_pXMLDoc->save(COleVariant(m_strFileName));
     m_pXMLDoc->Release();
    }
    /*
    * 函数名称: Init()
    * 说明:  初始化XML日志文件的工程信息
    * 参数: 
    *   无
    * 返回: 无
    */
    void CXMLLogfile::Init()
    {
     IXMLDOMNode *pAppNameNode, *pTimestamp, *pDate, *pTime;;
     TCHAR        *szTemp = new TCHAR[MAX_PATH];
     HRESULT hr ;

     CTime timeCur ;
     timeCur = CTime::GetCurrentTime();
     CString strDate, strTime;
     strDate = timeCur.Format(_T("%Y-%m-%d"));
     strTime = timeCur.Format(_T("%X"));

     //更改工程名称
     pAppNameNode = GetFirstLevelNode(_T("AppName"));
     hr = pAppNameNode->put_text(CComBSTR(AfxGetAppName()));
     pAppNameNode->Release();
    //* 
     //时间戳
     ZeroMemory(szTemp,MAX_PATH);
     double timestamp = TimeStamp();
     _stprintf(szTemp,_T("%.3f"),timestamp);
     pTimestamp = GetFirstLevelNode(_T("Timestamp"));
     hr = pTimestamp->put_text(CComBSTR(szTemp));
     pTimestamp->Release();
    //*/
     //日期
     pDate = GetFirstLevelNode(_T("Date"));
     hr = pDate->put_text(CComBSTR(strDate));
     pDate->Release(); 

     //时间
     pTime = GetFirstLevelNode(_T("Time"));
     hr = pTime->put_text(CComBSTR(strTime));
     pTime->Release();

     delete szTemp;
     Flush();
    }
    /*
    * 函数名称: DumpComError(_com_error &e)
    * 说明:  输出COM错误信息
    * 参数: 
    *   IN  _com_error &e COM错误信息对象
    * 返回: 无
    */
    void CXMLLogfile::DumpComError(_com_error &e)
    {
     _bstr_t bstrSource(e.Source());
     _bstr_t bstrDescription(e.Description());
     
     TRACE("Error/n");
     TRACE("/tCode = %08lx/n", e.Error());
     TRACE("/tCode meaning = %s/n", e.ErrorMessage());
     TRACE("/tSource = %s/n", (LPCSTR) bstrSource);
     TRACE("/tDescription = %s/n", (LPCSTR) bstrDescription);
    }
    /*
    * 函数名称: CreateLogFile(LPCTSTR lpszLogFilName)
    * 说明:  创建原始的XML日志文件
    * 参数: 
    *   IN  LPCTSTR lpszLogFileName 文件名称
    * 返回: true 成功
    */
    bool CXMLLogfile::CreateLogFile(LPCTSTR lpszLogFilName)
    {
     IXMLDOMDocument *pXMLDoc = NULL;

     BSTR bstr = NULL;
     VARIANT_BOOL status;
     HRESULT hr;

     try
     {
      hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
       IID_IXMLDOMDocument, (void**)&pXMLDoc);

      if (FAILED(hr))
       _com_issue_error(hr);

      bstr = ::SysAllocString(wszLogOrig);
      ASSERT(NULL != bstr);
      hr = pXMLDoc->loadXML(bstr,&status);
      ::SysFreeString(bstr);

      if (FAILED(hr))
       _com_issue_error(hr);

      if(status != VARIANT_TRUE)
      {
       return false;
      }

      hr = pXMLDoc->save(COleVariant(lpszLogFilName));
      if (FAILED(hr))
       _com_issue_error(hr);

      pXMLDoc->Release();
     }
     catch(_com_error &e)
     {
      DumpComError(e);
      return false;
     }
     return true;
    }
    /*
    * 函数名称: GetFirstLevelNode(LPCTSTR lpszNodeName)
    * 说明:  根据名称查找第一层子节点指针,没有则判断是否创建
    * 参数: 
    *   IN  LPCTSTR lpszNodeName 节点名称
    *   IN  BOOL bCreate 是否创建
    * 返回: IXMLDOMNode * 节点指针
    */
    IXMLDOMNode * CXMLLogfile::GetFirstLevelNode(LPCTSTR lpszNodeName,BOOL bCreate)
    {
     IXMLDOMElement *pRootNode = NULL, *element = NULL;
     IXMLDOMNode    *pLogItem = NULL, *pResultNode = NULL;
     CComBSTR       szName;
     bool           bSecFound = false, bEntryFound = false;
    // wchar_t        *szTemp = new wchar_t[255];

     m_pXMLDoc->get_documentElement(&pRootNode);
     
     for(pRootNode->get_firstChild(&pLogItem); pLogItem != NULL; pLogItem->get_nextSibling(&pLogItem))
     {
      pLogItem->get_baseName(&szName);

      if(szName == CComBSTR(lpszNodeName))
      {
       pResultNode = pLogItem;
       break;
      }
     }

     if(pLogItem == NULL && bCreate)
     {
      m_pXMLDoc->createElement(CComBSTR(lpszNodeName), &element);
      pRootNode->appendChild(element, &pLogItem);
      element->Release();
      pResultNode = pLogItem;
     }

     pRootNode->Release();
     
     return pResultNode;
    }
    /*
    * 函数名称: GetChildNode(LPCTSTR lpszParent, LPCTSTR lpszChild)
    * 说明:  查找父节点下的某一子节点指针,没有则判断是否创建创建
    * 参数: 
    *   IN  LPCTSTR lpszParent 父节点名称
    *   IN LPCTSTR lpszChild 子节点名称
    *   IN  BOOL bCreate    是否创建
    * 返回: IXMLDOMNode * 子节点指针
    */
    IXMLDOMNode * CXMLLogfile::GetChildNode(LPCTSTR lpszParent, LPCTSTR lpszChild,BOOL bCreate)
    {
     IXMLDOMElement *pRootNode= NULL, *element= NULL;
     IXMLDOMNode    *pLogItem= NULL, *pLogData= NULL, *pResultNode= NULL;
     CComBSTR       szName;

     m_pXMLDoc->get_documentElement(&pRootNode);
     
     for(pRootNode->get_firstChild(&pLogItem); pLogItem != NULL; pLogItem->get_nextSibling(&pLogItem))
     {
      pLogItem->get_baseName(&szName);

      if(szName == CComBSTR(lpszParent))
      {
       for(pLogItem->get_firstChild(&pLogData); pLogData != NULL; pLogData->get_nextSibling(&pLogData))
       {
        pLogData->get_baseName(&szName);

        if(szName == CComBSTR(lpszChild))
        {
         pResultNode = pLogData;    
         break;
        }
       }

       if(pLogData == NULL && bCreate)
       {
        m_pXMLDoc->createElement(CComBSTR(lpszChild), &element);
        pLogItem->appendChild(element, &pLogData);
        element->Release();
        pResultNode = pLogData;
       }
       pLogItem->Release();
       break;
      }
     }

     if(pLogItem == NULL && bCreate)
     {
      m_pXMLDoc->createElement(CComBSTR(lpszParent), &element);
      pRootNode->appendChild(element, &pLogItem);
      element->Release();
      m_pXMLDoc->createElement(CComBSTR(lpszChild), &element);
      pLogItem->appendChild(element, &pLogData);
      element->Release();
      pResultNode = pLogData;
     }
     
     pRootNode->Release();

     return pResultNode;
    }
    /*
    * 函数名称: AppendNode(IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue)
    * 说明:  在XML中添加一节点,并赋值为 lpszValue
    * 参数: 
    *   IN  IXMLDOMNode * pXMLItem 要添加节点的节点指针
    *   IN LPCTSTR lpszNodeName 添加的节点名称
    *   IN  LPCTSTR lpszComment  值
    */
    void CXMLLogfile::AppendNode(IXMLDOMNode * pXMLItem, LPCTSTR lpszNodeName, LPCTSTR lpszValue)
    {
     IXMLDOMElement *element;
     IXMLDOMNode *pLogData;

     m_pXMLDoc->createElement(CComBSTR(lpszNodeName),&element);
     pXMLItem->appendChild(element,&pLogData);
     element->Release();

     pLogData->put_text(CComBSTR(lpszValue));
     pLogData->Release(); 
    }
    /*
    * 函数名称: AppendItem(LPCTSTR lpszFileName,LPCTSTR lpszComment)
    * 说明:  在XML中添加一条日志
    * 参数: 
    *   IN LPCTSTR lpszFileName 文件信息
    *   IN  LPCTSTR lpszComment  错误信息
    */
    void CXMLLogfile::AppendItem(LPCTSTR lpszFileName,LPCTSTR lpszComment)
    {
     IXMLDOMElement *pRootNode, *element;
     IXMLDOMNode    *nLogItem;
     CComBSTR       szName;
     HRESULT hr;

     CTime timeCur ;
     timeCur = CTime::GetCurrentTime();
     CString strDate, strTime;
     strDate = timeCur.Format(_T("%Y-%m-%d"));
     strTime = timeCur.Format(_T("%X"));
     
     hr = m_pXMLDoc->get_documentElement(&pRootNode);

     m_pXMLDoc->createElement(CComBSTR(_T("LogItem")),&element);
     pRootNode->appendChild(element,&nLogItem);
     element->Release();

     AppendNode(nLogItem,_T("Date"),strDate);

     AppendNode(nLogItem,_T("Time"),strTime);

     AppendNode(nLogItem,_T("Filename"),lpszFileName);

     AppendNode(nLogItem,_T("comment"),lpszComment);


     pRootNode->Release();
    }
    /*
    * 函数名称: Flush()
    * 说明:  将缓冲区内数据写到磁盘保存XML文件
    * 参数: 
    *    无
    */
    void CXMLLogfile::Flush()
    {
     m_pXMLDoc->save(COleVariant(m_strFileName));
    }
    /*
    * 函数名称: Log(LPCTSTR lpszFilName,LPCTSTR s,...)
    * 说明:  添加一条日值记录
    * 参数: 
    *    LPCTSTR lpszFileName 文件信息
    *    LPCTSTR s    其他错误信息
    * EXAMPLE:
    *   Log(__FILE__,"%ld line error!!",__LINE__)
    */
    void CXMLLogfile::Log(LPCTSTR lpszFilName,LPCTSTR s,...)
    {
     static TCHAR szBuff[1024];
     va_list argptr;
     int cnt;

     va_start(argptr, s);
     cnt = _vstprintf(szBuff, s, argptr);
     va_end(argptr);
     
     AppendItem(lpszFilName,szBuff);
     Flush();
    }
    /*
    * 函数名称: ClearAll()
    * 说明:  清除日值
    * 参数: 
    *    无
    * 返回值:   成功 true
    */
    bool CXMLLogfile::ClearAll()
    {
     IXMLDOMElement *pRootNode= NULL;
     IXMLDOMNode    *pLogItem= NULL, *pLogData= NULL, *pOldNode= NULL, *pNextNode ,*pPreviousNode;
     CComBSTR       szName;
     HRESULT  hr ;
     m_pXMLDoc->get_documentElement(&pRootNode);
     try
     {
      pRootNode->get_lastChild(&pLogItem);
      do
      {
       pLogItem->get_previousSibling(&pPreviousNode);
        
       pLogItem->get_baseName(&szName);
       if(szName == CComBSTR(_T("LogItem")))
       {
        pLogItem->get_firstChild(&pLogData);
        do
        {
         pLogData->get_nextSibling(&pNextNode);

         pLogData->get_baseName(&szName);
         hr = pLogItem->removeChild(pLogData,&pOldNode);
         if (FAILED(hr))
          _com_issue_error(hr);
         pOldNode->Release();
         pOldNode = NULL;

         pLogData = pNextNode;
        }while(pLogData != NULL);
       }
       hr = pRootNode->removeChild(pLogItem,&pOldNode);

       if (FAILED(hr))
        _com_issue_error(hr);
       
       pLogItem = pPreviousNode;
      }while(pLogItem != NULL);
      pRootNode->Release();
     }
     catch(_com_error &e)
     {
      pRootNode->Release();
      DumpComError(e);
      return false;
     }
     Flush();
     return true;
    }

  • 相关阅读:
    AccessControlAllowOrigin 跨域设置多域名
    C#基于LibUsbDotNet实现USB通信(一)
    移动端设置行高等于高度的时候文本不居中???
    阿里云OSS设置跨域访问还是不行。
    没错,就是AccessControlAllowOrigin,跨域
    移动端 lineheight 文字不居中问题解决方案
    Chromium.org team 改进vs编译速度的一些建议
    isapi x86 在win7x64下的安装问题
    Entity Framwork one to one problem
    Google Talk使用技巧
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6314617.html
Copyright © 2020-2023  润新知