ITPub博客

首页 > 应用开发 > IT综合 > 利用XML文件的一个写日志的类!!!!! (转)

利用XML文件的一个写日志的类!!!!! (转)

原创 IT综合 作者:amyz 时间:2007-08-15 14:32:07 0 删除 编辑
利用XML文件的一个写日志的类!!!!! (转)[@more@]

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

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

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

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

XSL样式文件代码:

http://www.w3.org/1999/XSL/Transform">



 
  <xsl:value-of <A href="tag-73-1.html">select</A>="LogFile/AppName" /> 日志文件
 
 
 

运行日志文件

 


 
 
 
 

 
 
 
 
 
 
 

 
 


 
 
 
 
 
 
 
日期-时间错误信息具体位置信息
.

 

 
Log.xsl by force eagle <.NET">force_eagle@163.net>
mailto:force_eagle@163.net">force_eagle@163.net>>

 



以下是一日志表格图:

以下是源代码,需要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(" "
 " "
 " XXXX 1053925276.381 "
 "2003-05-26
")};
//*/
static WCHAR *wszLogOrig = {L" XXXX 1053925276.381 2003-05-26 "};

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 ");
 TRACE(" Code = %08lx ", e.Error());
 TRACE(" Code meaning = %s ", e.ErrorMessage());
 TRACE(" Source = %s ", (LPCSTR) bstrSource);
 TRACE(" Description = %s ", (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;
}


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10752019/viewspace-958210/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    3982
  • 访问量
    7895757